-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

require 'storage.client'

local mctp_service = require 'mctp.mctp_service'
local skynet = require 'skynet'
local utils = require 'mc.utils'
local vos = require 'utils.vos'
local class = require 'mc.class'
local log = require 'mc.logging'
local common_def = require 'common_def'
local file_sec = require 'utils.file'
local patition_mgmt = require 'os_patition.patition_mgmt'
local orm_object_manage = require 'mc.orm.object_manage'
local object_manager = require 'object_manager'
local diagnose_service = require 'diagnose.diagnose_service'
local drive_collection = require 'drive.drive_collection'
local volume_collection = require 'volume.volume_collection'
local array_collection = require 'array.array_collection'
local ipmi_service = require 'ipmi_service'
local metric_collect = require 'metric_collect'
local battery_collection = require 'battery.battery_collection'
local vpd_connector_collection = require 'nvme.vpd_connector_collection'
local replica_drive_collection = require 'nvme.replica_drive.replica_drive_collection'
local config_manager = require 'config_manager'
local reboot_manage = require 'mc.mdb.micro_component.reboot'
local mc_admin = require 'mc.mc_admin'
local c_tasks = require 'mc.orm.tasks'
local rpc_service_volume = require 'rpc_services.rpc_service_volume'
local rpc_service_drive = require 'rpc_services.rpc_service_drive'
local utils_core = require 'utils.core'
local object_manage = require 'mc.mdb.object_manage'
local import_export_eng = require 'handler.export_import_engine'
local ipmi = require 'storage.ipmi.ipmi'
local storage_bus = require 'storage_bus'
local mdb_config_manage = require 'mc.mdb.micro_component.config_manage'
local intf_debug = require'mc.mdb.micro_component.debug'
local link_volume_array_drive_service = require 'link_volume_array_drive_service'
local pd_identify_service = require 'pd.pd_identify_service'
local bus_monitor_service = require 'bus_monitor_service'
local c_bma = require 'bma'
local rpc_service_controller = require 'rpc_services.rpc_service_controller'
local rpc_service_nvme_drive = require 'rpc_services.rpc_service_nvme_drive'
local rpc_service_subhealth = require 'rpc_services.rpc_service_subhealth'
local c_storage_service = require 'storage.service'
local c_storageconfig = require 'storageconfig.storageconfig_object'
local storage_setting = require 'storage_setting.storage_setting'
local controller_collection = require 'controller.controller_collection'
local ctrl_commu_loss_monitor = require 'ctrl_commu_loss_monitor'
local c_drives_object = require 'drives.drives_object'

local storage_path = "/dev/shm/dump_info_tmp/dump_info/LogDump/storage"
local drive_log_path = "/data/var/log/storage/drivelog"
local phy_path = "/data/var/log/storage/phy"
local obj_info_path = "/data/var/log/storage/RAID_Controller_Info.txt"
local log_storage_path = "/data/var/log/storage"
local raid_lib_path = '/dev/shm/raid_controller_lib.log'

local storage_app = class(c_storage_service, nil, true)

function storage_app:ctor()
    self.storage_bus     = storage_bus.new(self)
    self.c_storageconfig = c_storageconfig.new(self)
    self.bma             = c_bma.new(self.bus)
    self.config_manager  = config_manager.new()
    self.storage_setting = storage_setting.collection
end

local function dump_obj_infos(fp_w)
    log:notice('Dumping bios_boot_stage')
    bus_monitor_service.get_instance():dump_objs_info(fp_w)
    log:notice('Dumping controllers info')
    controller_collection.get_instance():dump_objs_info(fp_w)
end

local function dump_nvme_log(self)
    -- 先创建drivelog下是否有Disk目录
    for _, obj in pairs(self.drive_collection.nvme_list) do
        if obj.nvme_mi_mctp_obj then
            obj.nvme_mi_mctp_obj:collect_nvme_log()
        end
    end
end

function storage_app:dump_log(ctx, path)
    if file_sec.check_real_path_s(storage_path) ~= common_def.RET_OK then
        utils.mkdir_with_parents(storage_path, utils.S_IRWXU | utils.S_IRGRP | utils.S_IXGRP)
    end

    dump_nvme_log(self)

    if file_sec.check_real_path_s(drive_log_path) == common_def.RET_OK then
        vos.system_s("/bin/cp", "-r", drive_log_path, storage_path)
    end

    if file_sec.check_real_path_s(phy_path) == common_def.RET_OK then
        vos.system_s("/bin/cp", "-r", phy_path, storage_path)
    end

    if utils_core.is_dir(common_def.CTRL_LOG_BASE_PATH) then
        vos.system_s("/bin/cp", "-r", common_def.CTRL_LOG_BASE_PATH, storage_path)
    else
        utils.mkdir_with_parents(string.format('%s/ctrllog', storage_path),
            utils.S_IRWXU | utils.S_IRGRP | utils.S_IXGRP)
    end

    if file_sec.check_real_path_s(log_storage_path) ~= 0 then
        utils.mkdir_with_parents(log_storage_path, utils.S_IRWXU | utils.S_IRGRP | utils.S_IXGRP)
    end
    local fp_w, err = file_sec.open_s(obj_info_path, 'w+')
    if not fp_w then
        log:error('open file failed, err: %s', err)
        return
    end
    local ok, ret = pcall(dump_obj_infos, fp_w)
    if not ok then
        log:error('dump_obj_infos failed, err: %s', ret)
    end
    fp_w:close()
    ret = file_sec.check_realpath_before_open_s(path)
    if ret ~= common_def.RET_OK then
        log:error('check path failed, err:%s', ret)
        return
    end
    vos.system_s("/bin/cp", obj_info_path, path)
    ok, ret = pcall(function()
        vos.system_s("/bin/cp", raid_lib_path, path)
        vos.system_s("/bin/cp", raid_lib_path .. '.1', path)
    end)
    if not ok then
        log:error('dump raid_controller_lib.log failed, err:%s', ret)
    end
end

function storage_app:init()
    skynet.fork_once(function()
        log:notice('storage-init start')
        storage_app.super.init(self)
        object_manage.disable_discovery()
        self.mc_obj_manager                  = orm_object_manage.get_instance(self.db, self.bus)
        self.object_manage                   = object_manager.new(self.bus)
        object_manage.enable_discovery(self.bus)
        self:check_dependencies()
        self.mc_obj_manager.app              = storage_app
        self.controller_collection           = controller_collection.new(self.persist)
        self.rpc_service_controller          = rpc_service_controller.new(self.bus)
        self.drive_collection                = drive_collection.new()
        self.rpc_service_drive               = rpc_service_drive.new()
        self.volume_collection               = volume_collection.new(self)
        self.rpc_service_volume              = rpc_service_volume.new(self.bus)
        self.array_collection                = array_collection.new(self)
        self.replica_drive_collection        = replica_drive_collection.new(self)
        self.battery_collection              = battery_collection.new(self)
        self.vpd_connector_collection        = vpd_connector_collection.new()
        self.bus_monitor_service             = bus_monitor_service.new(self.bus)
        self.ipmi_service                    = ipmi_service.new(self.db)
        self.link_volume_array_drive_service = link_volume_array_drive_service.new()
        self.pd_identify_service             = pd_identify_service.new(self.db)
        self.mctp_service                    = mctp_service.new()
        self.ctrl_commu_loss_monitor         = ctrl_commu_loss_monitor.new()
        self.metric_collect                  = metric_collect.new(self.bus)
        self.c_drives_object                 = c_drives_object.new(self)
        self.diagnose_service                = diagnose_service.new()
        -- 解决组件init超10s问题，因为对象间依赖，上面内容执行顺序不变，防止影响业务
        self.rpc_service_subhealth           = rpc_service_subhealth.new(self.bus)
        self.rpc_service_nvme_drive          = rpc_service_nvme_drive.new(self.bus)
        self:register_object_mgmt()
        self:register_reboot_methods()
        self:register_rpc()
        self:register_ipmi()
        self:import_export_engine_register()
        intf_debug.on_dump(function(ctx, path)
            self:dump_log(ctx, path)
        end)
        patition_mgmt.new(self.bus, self.reset_local_db, self)
        -- 等待各服务on_add_object都执行完之后再分发自发现对象
        self.mc_obj_manager:start()
        self:start_gc_task()
        log:notice('storage-init end')
    end)
end

function storage_app:start_gc_task()
    skynet.sleep(60000) -- 10分钟后开始启动收集任务
    c_tasks.get_instance():new_task("start collect garbage"):loop(function(task)
        collectgarbage('collect')
        utils_core.malloc_trim(0)
    end):set_timeout_ms(300000)
end

function storage_app:check_dependencies()
    local admin = mc_admin.new()
    admin:parse_dependency(utils_core.getcwd() .. '/mds/service.json')
    admin:check_dependency(self.bus)
end

function storage_app:on_reboot_prepare()
    log:notice("[storage_app] reboot prepare")
end

function storage_app:on_reboot_cancel()
    log:notice("[storage_app] reboot cancel")
end

function storage_app:on_reboot_action()
    log:notice("[storage_app] reboot action")
end

function storage_app:register_reboot_methods()
    -- 注册平滑重启回调函数
    -- Prepare准备重启回调
    reboot_manage.on_prepare(function()
        self:on_reboot_prepare()
        return 0
    end)
    -- Action执行重启回调
    reboot_manage.on_action(function()
        self:on_reboot_action()
        return 0
    end)
    -- Cancel取消重启回调
    reboot_manage.on_cancel(function()
        self:on_reboot_cancel()
    end)
end

function storage_app:init_on_add_object()
    object_manage.on_add_object(self.bus, function(class_name, object, position)
        self.config_manager:on_add_object(class_name, object, position)
    end)
end

function storage_app:init_on_delete_object()
    object_manage.on_delete_object(self.bus, function(class_name, object, position)
        self.config_manager:on_delete_object(class_name, object, position)
    end)
end

function storage_app:register_object_mgmt()
    -- 添加对象回调
    self:init_on_add_object()
    -- 删除对象回调
    self:init_on_delete_object()
end

-- 注册drive的ipmi命令
function storage_app:register_ipmi_service()
    -- 获取类
    self:register_ipmi_cmd(ipmi.GetHddPwrStatus,                   ipmi_service.get_hdd_pwr_status)
    self:register_ipmi_cmd(ipmi.GetControllerList,                 ipmi_service.get_controller_list)
    self:register_ipmi_cmd(ipmi.GetControllerFwVersion,            ipmi_service.get_controller_fw_version)
    self:register_ipmi_cmd(ipmi.GetControllerNvdataVersion,        ipmi_service.get_controller_nvdata_version)
    self:register_ipmi_cmd(ipmi.GetControllerInfo,                 ipmi_service.get_controller_info)
    self:register_ipmi_cmd(ipmi.GetLogicalDriveList,               ipmi_service.get_logical_drive_list)
    self:register_ipmi_cmd(ipmi.GetCachecadeAssociatedLds,         ipmi_service.get_cachecade_associated_lds)
    self:register_ipmi_cmd(ipmi.GetLogicalDrivePds,                ipmi_service.get_logical_drive_pds)
    self:register_ipmi_cmd(ipmi.GetLogicalDriveListEx,             ipmi_service.get_logical_drive_list_ex)
    self:register_ipmi_cmd(ipmi.GetCachecadeAssociatedLdsEx,       ipmi_service.get_cachecade_associated_lds_ex)
    self:register_ipmi_cmd(ipmi.GetControllerPds,                  ipmi_service.get_controller_pds)
    self:register_ipmi_cmd(ipmi.GetPhysicalDriveLocation,          ipmi_service.get_physical_drive_location)
    self:register_ipmi_cmd(ipmi.GetPhysicalDriveInfo,              ipmi_service.get_physical_drive_info)
    self:register_ipmi_cmd(ipmi.GetPhysicalDriveLedStatus,         ipmi_service.get_physical_drive_led_status)
    self:register_ipmi_cmd(ipmi.GetArrayList,                      ipmi_service.get_array_list)
    self:register_ipmi_cmd(ipmi.GetArrayInfo,                      ipmi_service.get_array_info)
    self:register_ipmi_cmd(ipmi.GetArrayLds,                       ipmi_service.get_array_lds)
    self:register_ipmi_cmd(ipmi.GetArrayPds,                       ipmi_service.get_array_pds)
    self:register_ipmi_cmd(ipmi.GetControllerCapability,           ipmi_service.get_controller_capability)
    self:register_ipmi_cmd(ipmi.GetArrayLdsEx,                     ipmi_service.get_array_lds_ex)
    self:register_ipmi_cmd(ipmi.GetDiskManufacturer,               ipmi_service.get_manufacturer)
    self:register_ipmi_cmd(ipmi.GetLogAutoCollectConfig,           ipmi_service.get_log_auto_collect_config)

    -- 设置类
    self:register_ipmi_cmd(ipmi.CreateLogicalDriveOnNewArray,      ipmi_service.create_logical_drive_on_new_array)
    self:register_ipmi_cmd(ipmi.CreateCachecadeLogicalDrive,       ipmi_service.create_cachecade_logical_drive)
    self:register_ipmi_cmd(ipmi.CreateLogicalDriveOnExistedArray,  ipmi_service.create_logical_drive_on_existed_array)
    self:register_ipmi_cmd(ipmi.DeleteLogicalDrive,                ipmi_service.delete_logical_drive)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveName,               ipmi_service.set_logical_drive_name)
    self:register_ipmi_cmd(ipmi.SetLogicDriveRp,                   ipmi_service.set_logic_drive_rp)
    self:register_ipmi_cmd(ipmi.SetLogicDriveWp,                   ipmi_service.set_logic_drive_wp)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveIOP,                ipmi_service.set_logical_drive_iop)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveAP,                 ipmi_service.set_logical_drive_ap)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveDCP,                ipmi_service.set_logical_drive_dcp)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveBGI,                ipmi_service.set_logical_drive_bgi)
    self:register_ipmi_cmd(ipmi.SetLogicalDriveCachecade,          ipmi_service.set_logical_drive_cachecade)
    self:register_ipmi_cmd(ipmi.SetLogicDriveBootable,             ipmi_service.set_logic_drive_bootable)
    self:register_ipmi_cmd(ipmi.SetControllerCopyback,             ipmi_service.set_controller_copyback)
    self:register_ipmi_cmd(ipmi.SetControllerSmarterCopyback,      ipmi_service.set_controller_smarter_copyback)
    self:register_ipmi_cmd(ipmi.SetControllerRestoreSettings,      ipmi_service.set_controller_restore_settings)
    self:register_ipmi_cmd(ipmi.SetControllerJbod,                 ipmi_service.set_controller_jbod)
    self:register_ipmi_cmd(ipmi.SetControllerOutofband,            ipmi_service.set_controller_outofband)
    self:register_ipmi_cmd(ipmi.GetDiskSilk,                       ipmi_service.get_disk_silk)
    self:register_ipmi_cmd(ipmi.GetRaidControllerTemp,             ipmi_service.get_raid_controller_temp)
    self:register_ipmi_cmd(ipmi.SetLocationIndicatorState,         ipmi_service.set_location_indicator_state)
    self:register_ipmi_cmd(ipmi.SetFaultIndicatorState,            ipmi_service.set_fault_indicator_state)
    self:register_ipmi_cmd(ipmi.SetHotspareType,                   ipmi_service.set_hotspare_type)
    self:register_ipmi_cmd(ipmi.SetFirmwareStatus,                 ipmi_service.set_firmware_status)
    self:register_ipmi_cmd(ipmi.SetControllerOutofband,            ipmi_service.set_controller_outofband)
    self:register_ipmi_cmd(ipmi.SetRaidFaultStatus,                ipmi_service.set_raid_fault_status)
    self:register_ipmi_cmd(ipmi.SetPCHDiskInfo,                    ipmi_service.set_pch_disk_info)
    self:register_ipmi_cmd(ipmi.SetLogAutoCollectConfig,           ipmi_service.set_log_auto_collect_config)
    -- 主动触发硬盘日志收集
    self:register_ipmi_cmd(ipmi.SetPdLogCollect,                   ipmi_service.set_pd_log_collect)
    self:register_ipmi_cmd(ipmi.StartDriveCollectLog,              ipmi_service.start_drive_collect_log)
end

-- 注册模块的IPMI命令
function storage_app:register_ipmi()
    self:register_ipmi_service()
end

-- 注册drive的通用rpc方法
function storage_app:register_drive_rpc()
    -- 调试打印运行时硬盘信息
    self:ImplStorageConfigReleaseStorageDriveGetDriveDetails(function (obj, ctx, ...)
        return self.rpc_service_drive:get_drive_info_by_name(...)
    end)
    -- 设置物理盘的定位灯状态
    self:ImplDriveSystemsStorageDriveSetLocationIndicatorState(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetLocationIndicatorState', obj.Name, ctx, ...)
    end)

    -- 设置物理盘的故障灯状态
    self:ImplDriveSystemsStorageDriveSetFaultIndicatorState(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetFaultIndicatorState', obj.Name, ctx, ...)
    end)

    -- 支持设置物理盘的固件状态
    self:ImplDriveSystemsStorageDriveSetFirmwareStatus(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetFirmwareStatus', obj.Name, ctx, ...)
    end)

    -- 支持设置物理盘是否为热备盘
    self:ImplDriveSystemsStorageDriveSetHotspareType(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetHotspareType', obj.Name, ctx, ...)
    end)

    -- 设置物理盘的启动优先级
    self:ImplDriveSystemsStorageDriveSetBootPriority(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetBootPriority', obj.Name, ctx, ...)
    end)

    -- 支持设置物理盘的巡检状态
    self:ImplDriveSystemsStorageDriveSetPatrolState(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('SetPatrolState', obj.Name, ctx, ...)
    end)

    self:ImplDriveMetricGetItems(function (obj, ctx, ...)
        return self.metric_collect:get_drive_data_collection_items(obj, ...)
    end)

    self:ImplDriveMetricGetData(function (obj, ctx, ...)
        return self.metric_collect:get_drive_data_collection_data(obj, ...)
    end)

    -- 加密擦除
    self:ImplDriveSystemsStorageDriveCryptoErase(function (obj, ctx, ...)
        return self.rpc_service_drive:drive_operate('CrypoErase', obj.Name, ctx, ...)
    end)

    -- 调试硬盘冗余块多级监控功能
    self:ImplStorageConfigRecordDriveSpareBlockMockRecordSpareBlock(function (obj, ctx, ...)
        return self.rpc_service_drive:mock_record_spare_block(...)
    end)
end

-- 注册控制器的通用rpc方法
function storage_app:register_ctrl_rpc()
    -- 调试打印运行时RAID卡的数据
    self:ImplStorageConfigReleaseStorageControllerGetControllerInfo(function(obj, ctx, ...)
        return self.rpc_service_controller:get_controller_info(...)
    end)

    -- 设置控制器的回拷开关
    self:ImplControllerSystemsStorageControllerSetCopybackState(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetCopyBackState", obj.Id, ctx, ...)
    end)

    -- 设置控制器的JBOD开关
    self:ImplControllerSystemsStorageControllerSetJBODState(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetJBODState", obj.Id, ctx, ...)
    end)

    -- 设置控制器的Smart回拷开关
    self:ImplControllerSystemsStorageControllerSetSmarterCopyBackState(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetSmarterCopyBackState", obj.Id, ctx, ...)
    end)

    self:ImplControllerSystemsStorageControllerSetMaintainPDFailHistoryState(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetMaintainPDFailHistoryState", obj.Id, ctx, ...)
    end)

    -- 恢复控制器的默认配置
    self:ImplControllerSystemsStorageControllerRestoreDefaultSettings(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("RestoreDefaultSettings", obj.Id, ctx, ...)
    end)

    -- 设置启动设备
    self:ImplControllerSystemsStorageControllerSetBootDevices(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetBootDevices", obj.Id, ctx, ...)
    end)

    -- 设置工作模式
    self:ImplControllerSystemsStorageControllerSetWorkMode(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetWorkMode", obj.Id, ctx, ...)
    end)

    -- 一键清除外部配置
    self:ImplControllerSystemsStorageControllerClearForeignConfig(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("ClearForeignConfig", obj.Id, ctx, ...)
    end)

    -- 一键导入外部配置
    self:ImplControllerSystemsStorageControllerImportForeignConfig(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("ImportForeignConfig", obj.Id, ctx, ...)
    end)

    -- 设置控制器无电池写缓存状态
    self:ImplControllerSystemsStorageControllerSetNoBatteryWriteCache(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetNoBatteryWriteCache", obj.Id, ctx, ...)
    end)

    -- 设置控制器读缓存百分比
    self:ImplControllerSystemsStorageControllerSetReadCachePercent(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetReadCachePercent", obj.Id, ctx, ...)
    end)

    -- 设置控制器写缓存策略
    self:ImplControllerSystemsStorageControllerSetWriteCachePolicy(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("SetWriteCachePolicy", obj.Id, ctx, ...)
    end)

    -- 收集RAID控制器日志
    self:ImplControllerSystemsStorageControllerDumpLog(function(obj, ctx, ...)
        return self.rpc_service_controller:ctrl_operate("DumpLog", obj.Id, ctx, ...)
    end)

    -- 导入导出注册
    mdb_config_manage.on_import(function(ctx, config_data, import_type)
        import_export_eng.import(ctx, config_data, import_type)
    end)
    mdb_config_manage.on_export(function(ctx, export_type)
        return import_export_eng.export(ctx, export_type)
    end)
end

function storage_app:register_life_cycle_retirement()
    -- 控制器数据报废
    self:ImplControllerRetirementDataWipe(function(obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_operate("Retirement", controller_obj.Id, "DataWipe", ...)
    end)

    -- 获取数据报废报告
    self:ImplControllerRetirementGetReport(function(obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_operate("Retirement", controller_obj.Id, "GetReport",...)
    end)

end

-- 注册控制器的一致性校验rpc方法
function storage_app:register_ctrl_rpc_consistency_check()
    -- 打开一致性校验功能
    self:ImplControllerConsistencyCheckEnable(function(obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_operate("EnableCCheck", controller_obj.Id, ctx, ...)
    end)

    -- 关闭一致性校验功能
    self:ImplControllerConsistencyCheckDisable(function(obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_operate("DisableCCheck", controller_obj.Id, ctx, ...)
    end)

    -- 设置一致性校验功能
    self:ImplControllerConsistencyCheckSetParameters(function(obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_operate("SetCCheck", controller_obj.Id, ctx, ...)
    end)
end

-- 注册控制器创建删除逻辑盘方法
function storage_app:register_ctrl_rpc_volume_manage()
    -- 在已有阵列上创建逻辑盘
    self:ImplControllerVolumeManageCreateVolumeInExisingtArray(function (obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_task_operate("CreateVolumeInExistingArray",
            obj.path, controller_obj.Id, ctx, ...)
    end)

    -- 删除逻辑盘
    self:ImplControllerVolumeManageDeleteVolume(function (obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_task_operate("DeleteVolume", obj.path, controller_obj.Id, ctx, ...)
    end)

    -- 在全新阵列上创建逻辑盘
    self:ImplControllerVolumeManageCreateVolumeInNewArray(function (obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_task_operate("CreateVolumeInNewArray", obj.path,
            controller_obj.Id, ctx, ...)
    end)

    -- 创建cachecade逻辑盘
    self:ImplControllerVolumeManageCreateCachecadeVolume(function (obj, ctx, ...)
        local controller_obj = self.controller_collection.intf_map[obj]
        return self.rpc_service_controller:ctrl_task_operate("CreateCacheCadeVolume",
            obj.path, controller_obj.Id, ctx, ...)
    end)
end

-- 注册volume的通用rpc方法
function storage_app:register_volume_rpc()
    self:ImplVolumeVolumeSetName(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetName", obj.RefControllerId, obj.Id, ctx, ...)
    end)

    self:ImplVolumeVolumeSetReadPolicy(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetReadPolicy", obj.RefControllerId, obj.Id, ctx, ...)
    end)

    self:ImplVolumeVolumeSetWritePolicy(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetWritePolicy", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetBootable(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetBootable", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetIOPolicy(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetIOPolicy", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetBGIEnable(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetBGIEnable", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetAccessPolicy(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetAccessPolicy", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetDiskCachePolicy(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetDiskCachePolicy", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeStartForegroundInit(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_task_operate("StartFGI", obj.path, obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeCancelForegroundInit(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_task_operate("CancelFGI", obj.path, obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetCachecadeEnable(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetCachecadeEnable", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetAccelerator(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetAccelerator", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetCapacitySize(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetCapacitySize", obj.RefControllerId, obj.Id, ctx, ...)
    end)
    self:ImplVolumeVolumeSetStripSize(function (obj, ctx, ...)
        return self.rpc_service_volume:volume_operate("SetStripSize", obj.RefControllerId, obj.Id, ctx, ...)
    end)
end

-- 注册调试类的通用rpc方法
function storage_app:register_debug_rpc()
    self:ImplStorageConfigPhyBitErrorMockData(function (obj, ctx, ...)
        return self.diagnose_service:mock_phy_data(...)
    end)
end

-- 注册drives的通用rpc方法
function storage_app:register_subhealth_diagnose_rpc()
    self:ImplDrivesDrivesCollectIODeteriorationDiagInfo(function (obj, ctx, ...)
        return self.rpc_service_subhealth:collect_io_deterioration_diagnose_info
            ("CollectIODeteriorationDiagInfo", ...)
    end)
    self:ImplDrivesDrivesGetDrivesSubHealthDiagInfo(function (obj, ctx, subhealth_type)
        return self.rpc_service_subhealth:get_drives_subhealth_diagnose_info(subhealth_type)
    end)
    self:ImplDrivesDrivesSetDriveSubHealthDiagResult(function (obj, ctx, subhealth_diag_result_list)
        return self.rpc_service_subhealth:set_drive_subhealth_diag_result(subhealth_diag_result_list)
    end)
    self:ImplDrivesDrivesStartCollectLog(function (obj, ctx, drive_name)
        return self.rpc_service_subhealth:start_collect_log(ctx, drive_name)
    end)
    self:ImplDriveDriveDiagnoseCollectDiagnoseData(function (obj, ctx, ...)
        return self.rpc_service_subhealth:collect_drive_diagnose_data(obj.path, ctx, ...)
    end)

    self:ImplDriveDriveDiagnoseGetDiagnoseData(function (obj, ctx, ...)
        return self.rpc_service_subhealth:get_drive_diagnose_data(obj.path, ctx, ...)
    end)
end

-- 注册nvme盘的通用rpc方法
function storage_app:register_nvme_rpc()
    self:ImplDrivesDrivesGetNvmeDriveRawData(function (obj, ctx, index)
        return self.rpc_service_nvme_drive:get_nvme_drive_rawdata(index)
    end)
    self:ImplDrivesDrivesGetNvmeDriveCount(function (obj, ctx, ...)
        return self.rpc_service_nvme_drive:get_nvme_drive_count(...)
    end)
    self:ImplDriveNVMeGetSmartInfo(function (obj, ctx, ...)
        return self.rpc_service_nvme_drive:get_smart_info(obj.path, ...)
    end)
    self:ImplDriveNVMeSendNvmeMICommand(function (obj, ctx, ...)
        return self.rpc_service_nvme_drive:send_nvmemi_command(obj.path, ...)
    end)
    self:ImplDriveNVMeGetTelemetryData(function (obj, ctx, ...)
        return self.rpc_service_nvme_drive:get_telemetry_data(obj.path, self.bus, ...)
    end)
    self:ImplDriveNVMeGetIdentifyData(function (obj, ctx, ...)
        return self.rpc_service_nvme_drive:get_identify_data(obj.path, ...)
    end)
end

-- 注册模块的通用rpc方法
function storage_app:register_rpc()
    self:register_drive_rpc()
    self:register_ctrl_rpc()
    self:register_volume_rpc()
    self:register_ctrl_rpc_consistency_check()
    self:register_ctrl_rpc_volume_manage()
    self:register_debug_rpc()
    self:register_life_cycle_retirement()
    self:register_subhealth_diagnose_rpc()
    self:register_nvme_rpc()
end

-- 往导入导出引擎注册信息
function storage_app:import_export_engine_register()
    import_export_eng.register_config_dealer("RaidController", self.rpc_service_controller)
end

return storage_app