/*
 * Copyright 2018 JDCLOUD.COM
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http:#www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Statistics APIs
 * 资源统计相关接口
 *
 * OpenAPI spec version: v1
 * Contact:
 *
 * NOTE: This class is auto generated by the jdcloud code generator program.
 */

require('../../../lib/node_loader')
var JDCloud = require('../../../lib/core')
var Service = JDCloud.Service
var serviceId = 'monitor'
Service._services[serviceId] = true

/**
 * monitor service.
 * @version 1.3.9
 */

JDCloud.MONITOR = class MONITOR extends Service {
  constructor (options = {}) {
    options._defaultEndpoint = {}
    options._defaultEndpoint.protocol =
      options._defaultEndpoint.protocol || 'https'
    options._defaultEndpoint.host =
      options._defaultEndpoint.host || 'monitor.jdcloud-api.com'
    options.basePath = '/v1' // 默认要设为空""
    super(serviceId, options)
  }

  /**
      *  查询报警历史
检索条件组合优先级从高到低为
1：alarmIds不为空
2：alarmId不为空
3：serviceCode不为空
3.1：serviceCode + resourceId
3.2: serviceCode + resourceIds
3.3: serviceCode + ruleName
4：serviceCodes不为空
4.1：serviceCode + resourceId
4.2: serviceCode + resourceIds
4.3: serviceCode + ruleName
5: 所有规则
      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {string} [opts.serviceCode] - 产品线标识,默认返回该serviceCode下所有group的数据。eg:serviceCode&#x3D;jdw（jdw产品线下包含jdw-master与jdw-segment两个分组)会返回jdw-master和jdw-segment的数据。  optional
      * @param {string} [opts.groupCode] - 分组标识、指定该参数时，查询只返回该group的数据。groupCode参数仅在与serviceCode匹配时生效；eg:serviceCode&#x3D;jdw、groupCode&#x3D;jdw-master,只返回jdw-master分组的数据，不返回jdw-segment的数据。  optional
      * @param {string} [opts.resourceId] - 资源Id  optional
      * @param {string} [opts.alarmId] - 规则Id  optional
      * @param {integer} [opts.alarming] - 正在报警, 取值为1  optional
      * @param {string} [opts.startTime] - 开始时间  optional
      * @param {string} [opts.endTime] - 结束时间  optional
      * @param {integer} [opts.ruleType] - 规则类型,默认查询1， 1表示资源监控，6表示站点监控,7表示可用性监控  optional
      * @param {filter} [opts.filters] - serviceCodes - 产品线servicecode，精确匹配，支持多个
resourceIds - 资源Id，精确匹配，支持多个（必须指定serviceCode才会在该serviceCode下根据resourceIds过滤，否则该参数不生效）
alarmIds - 规则Id，精确匹配，支持多个
ruleName - 规则名称，模糊匹配，支持单个  optional
      * @param {string} [opts.resourceIdList] - resourceId列表，必须指定serviceCode才会生效  optional
      * @param {string} [opts.serviceCodeList] - 产品线列表  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param describedAlarmHistory alarmHistoryList
      * @param integer total  总数
      */

  describeAlarmHistory (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeAlarmHistory"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.groupCode !== undefined && opts.groupCode !== null) {
      queryParams['groupCode'] = opts.groupCode
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    if (opts.alarmId !== undefined && opts.alarmId !== null) {
      queryParams['alarmId'] = opts.alarmId
    }
    if (opts.alarming !== undefined && opts.alarming !== null) {
      queryParams['alarming'] = opts.alarming
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      queryParams['startTime'] = opts.startTime
    }
    if (opts.endTime !== undefined && opts.endTime !== null) {
      queryParams['endTime'] = opts.endTime
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      queryParams['ruleType'] = opts.ruleType
    }
    Object.assign(queryParams, this.buildFilterParam(opts.filters, 'filters'))
    Object.assign(
      queryParams,
      this.buildArrayParam(opts.resourceIdList, 'resourceIdList')
    )
    Object.assign(
      queryParams,
      this.buildArrayParam(opts.serviceCodeList, 'serviceCodeList')
    )

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeAlarmHistory with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarmHistory',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询规则, 查询参数组合及优先级从高到低为：
1：alarmIds不为空
2：alarmId不为空
3：serviceCode不为空
3.1：serviceCode + resourceId
3.2: serviceCode + resourceIds
3.3: serviceCode + ruleName
4：serviceCodes不为空
4.1：serviceCode + resourceId
4.2: serviceCode + resourceIds
4.3: serviceCode + ruleName
5: 所有规则
      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {string} [opts.serviceCode] - 产品线标识,默认返回该serviceCode下所有group的数据。eg:serviceCode&#x3D;jdw（jdw产品线下包含jdw-master与jdw-segment两个分组)会返回jdw-master和jdw-segment的数据。  optional
      * @param {string} [opts.groupCode] - 分组标识、指定该参数时，查询只返回该group的数据。groupCode参数仅在与serviceCode匹配时生效；eg:serviceCode&#x3D;jdw、groupCode&#x3D;jdw-master,只返回jdw-master分组的数据，不返回jdw-segment的数据。  optional
      * @param {string} [opts.resourceId] - 资源ID,根据resourceId查询时必须指定serviceCode才会生效  optional
      * @param {integer} [opts.ruleType] - 规则类型, 1表示资源监控，6表示站点监控,7表示可用性监控  optional
      * @param {integer} [opts.status] - 规则报警状态, 1：正常, 2：报警，4：数据不足  optional
      * @param {integer} [opts.enabled] - 规则状态：1为启用，0为禁用  optional
      * @param {integer} [opts.isAlarming] - 是否为正在报警的规则，0为忽略，1为是，与 status 同时只能生效一个,isAlarming 优先生效  optional
      * @param {string} [opts.alarmId] - 规则的id，若指定filter的alarmIds过滤时，忽略该参数  optional
      * @param {filter} [opts.filters] - 服务码或资源Id列表
serviceCodes - 产品线servicecode，精确匹配，支持多个
resourceIds - 资源Id，精确匹配，支持多个（必须指定serviceCode才会在该serviceCode下根据resourceIds过滤，否则该参数不生效）
alarmIds - 规则id，精确匹配，支持多个
ruleName - 规则名称，模糊匹配，支持单个  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param describedAlarm alarmList
      * @param integer total  规则总数
      */

  describeAlarms (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeAlarms"
      )
    }

    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.groupCode !== undefined && opts.groupCode !== null) {
      queryParams['groupCode'] = opts.groupCode
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      queryParams['ruleType'] = opts.ruleType
    }
    if (opts.status !== undefined && opts.status !== null) {
      queryParams['status'] = opts.status
    }
    if (opts.enabled !== undefined && opts.enabled !== null) {
      queryParams['enabled'] = opts.enabled
    }
    if (opts.isAlarming !== undefined && opts.isAlarming !== null) {
      queryParams['isAlarming'] = opts.isAlarming
    }
    if (opts.alarmId !== undefined && opts.alarmId !== null) {
      queryParams['alarmId'] = opts.alarmId
    }
    Object.assign(queryParams, this.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeAlarms with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  创建报警规则，可以为某一个实例创建报警规则，也可以为多个实例同时创建报警规则。
      * @param {Object} opts - parameters
      * @param {string} opts.clientToken - 幂等性校验参数,最长36位,若两个请求clientToken相等，则返回第一次创建的规则id，只创建一次规则
      * @param {createAlarmParam} opts.createAlarmSpec
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string alarmIdList
      */

  createAlarm (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  createAlarm"
      )
    }

    opts = opts || {}

    if (opts.clientToken === undefined || opts.clientToken === null) {
      throw new Error(
        "Missing the required parameter 'opts.clientToken' when calling createAlarm"
      )
    }
    if (opts.createAlarmSpec === undefined || opts.createAlarmSpec === null) {
      throw new Error(
        "Missing the required parameter 'opts.createAlarmSpec' when calling createAlarm"
      )
    }

    let postBody = {}
    if (opts.clientToken !== undefined && opts.clientToken !== null) {
      postBody['clientToken'] = opts.clientToken
    }
    if (opts.createAlarmSpec !== undefined && opts.createAlarmSpec !== null) {
      postBody['createAlarmSpec'] = opts.createAlarmSpec
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call createAlarm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  删除规则
      * @param {Object} opts - parameters
      * @param {string} opts.ids - 待删除的规则id，用逗号,分隔
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  deleteAlarms (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  deleteAlarms"
      )
    }

    opts = opts || {}

    if (opts.ids === undefined || opts.ids === null) {
      throw new Error(
        "Missing the required parameter 'opts.ids' when calling deleteAlarms"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.ids !== undefined && opts.ids !== null) {
      queryParams['ids'] = opts.ids
    }

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call deleteAlarms with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms',
      'DELETE',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询规则详情
      * @param {Object} opts - parameters
      * @param {string} opts.alarmId - 规则id
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param alarm alarm
      */

  describeAlarmsByID (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeAlarmsByID"
      )
    }

    opts = opts || {}

    if (opts.alarmId === undefined || opts.alarmId === null) {
      throw new Error(
        "Missing the required parameter 'opts.alarmId' when calling describeAlarmsByID"
      )
    }

    let postBody = null
    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      alarmId: opts.alarmId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeAlarmsByID with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms/{alarmId}',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  修改已创建的报警规则
      * @param {Object} opts - parameters
      * @param {string} opts.alarmId - 规则id
      * @param {array} [opts.contacts] - 通知联系人  optional
      * @param {baseRule} opts.rule
      * @param {string} [opts.webHookContent] - 回调content 注：仅webHookUrl和webHookContent均不为空时，才会创建webHook  optional
      * @param {string} [opts.webHookProtocol] - webHook协议，目前支持http，https  optional
      * @param {string} [opts.webHookSecret] - 回调secret，用户请求签名，防伪造  optional
      * @param {string} [opts.webHookUrl] - 回调url，例如http://www.jdcloud.com  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  updateAlarm (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  updateAlarm"
      )
    }

    opts = opts || {}

    if (opts.alarmId === undefined || opts.alarmId === null) {
      throw new Error(
        "Missing the required parameter 'opts.alarmId' when calling updateAlarm"
      )
    }
    if (opts.rule === undefined || opts.rule === null) {
      throw new Error(
        "Missing the required parameter 'opts.rule' when calling updateAlarm"
      )
    }

    let postBody = {}
    if (opts.contacts !== undefined && opts.contacts !== null) {
      postBody['contacts'] = opts.contacts
    }
    if (opts.rule !== undefined && opts.rule !== null) {
      postBody['rule'] = opts.rule
    }
    if (opts.webHookContent !== undefined && opts.webHookContent !== null) {
      postBody['webHookContent'] = opts.webHookContent
    }
    if (opts.webHookProtocol !== undefined && opts.webHookProtocol !== null) {
      postBody['webHookProtocol'] = opts.webHookProtocol
    }
    if (opts.webHookSecret !== undefined && opts.webHookSecret !== null) {
      postBody['webHookSecret'] = opts.webHookSecret
    }
    if (opts.webHookUrl !== undefined && opts.webHookUrl !== null) {
      postBody['webHookUrl'] = opts.webHookUrl
    }

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      alarmId: opts.alarmId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call updateAlarm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms/{alarmId}',
      'PATCH',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询规则的报警联系人
      * @param {Object} opts - parameters
      * @param {string} opts.alarmId - 规则id
      * @param {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {integer} [opts.referenceType] - 联系人类型。0,联系人分组; 1,联系人  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param describedNoticeContacts contactsList
      * @param integer total  报警联系人总数
      */

  describeAlarmContacts (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeAlarmContacts"
      )
    }

    opts = opts || {}

    if (opts.alarmId === undefined || opts.alarmId === null) {
      throw new Error(
        "Missing the required parameter 'opts.alarmId' when calling describeAlarmContacts"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    if (opts.referenceType !== undefined && opts.referenceType !== null) {
      queryParams['referenceType'] = opts.referenceType
    }

    let pathParams = {
      regionId: regionId,
      alarmId: opts.alarmId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeAlarmContacts with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms/{alarmId}/contacts',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  禁用报警规则。报警规则禁用后，将停止探测实例的监控项数据。
      * @param {Object} opts - parameters
      * @param {string} opts.alarmId - 规则 id
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  disableAlarm (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  disableAlarm"
      )
    }

    opts = opts || {}

    if (opts.alarmId === undefined || opts.alarmId === null) {
      throw new Error(
        "Missing the required parameter 'opts.alarmId' when calling disableAlarm"
      )
    }

    let postBody = {}

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      alarmId: opts.alarmId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call disableAlarm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms/{alarmId}/disable',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  启用报警规则，当客户的报警规则处于停止状态时，可以使用此接口启用报警规则。
      * @param {Object} opts - parameters
      * @param {string} opts.alarmId - 规则id
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  enableAlarm (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  enableAlarm"
      )
    }

    opts = opts || {}

    if (opts.alarmId === undefined || opts.alarmId === null) {
      throw new Error(
        "Missing the required parameter 'opts.alarmId' when calling enableAlarm"
      )
    }

    let postBody = {}

    let queryParams = {}

    let pathParams = {
      regionId: regionId,
      alarmId: opts.alarmId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call enableAlarm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/alarms/{alarmId}/enable',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询报警历史
检索条件组合优先级从高到低为
1：alarmIds不为空
2：alarmId不为空
3：serviceCode不为空
3.1：serviceCode + resourceId
3.2: serviceCode + resourceIds
3.3: serviceCode + ruleName
4：serviceCodes不为空
4.1：serviceCode + resourceId
4.2: serviceCode + resourceIds
4.3: serviceCode + ruleName
5: 所有规则
      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {string} [opts.serviceCode] - 产品线标识,默认返回该serviceCode下所有group的数据。eg:serviceCode&#x3D;jdw（jdw产品线下包含jdw-master与jdw-segment两个分组)会返回jdw-master和jdw-segment的数据。  optional
      * @param {string} [opts.groupCode] - 分组标识、指定该参数时，查询只返回该group的数据。groupCode参数仅在与serviceCode匹配时生效；eg:serviceCode&#x3D;jdw、groupCode&#x3D;jdw-master,只返回jdw-master分组的数据，不返回jdw-segment的数据。  optional
      * @param {string} [opts.resourceId] - 资源Id  optional
      * @param {string} [opts.alarmId] - 规则Id  optional
      * @param {integer} [opts.alarming] - 正在报警, 取值为1  optional
      * @param {string} [opts.startTime] - 开始时间  optional
      * @param {string} [opts.endTime] - 结束时间  optional
      * @param {integer} [opts.ruleType] - 规则类型,默认查询1， 1表示资源监控，6表示站点监控,7表示可用性监控  optional
      * @param {filter} [opts.filters] - serviceCodes - 产品线servicecode，精确匹配，支持多个
resourceIds - 资源Id，精确匹配，支持多个（必须指定serviceCode才会在该serviceCode下根据resourceIds过滤，否则该参数不生效）
alarmIds - 规则Id，精确匹配，支持多个
ruleName - 规则名称，模糊匹配，支持单个  optional
      * @param {string} [opts.resourceIdList] - resourceId列表，必须指定serviceCode才会生效  optional
      * @param {string} [opts.serviceCodeList] - 产品线列表  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param alarmHistoryWithDetail list
      * @param integer total  总数
      */

  describeAlarmHistoryAllRegion (opts, callback) {
    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.pageNumber !== undefined && opts.pageNumber !== null) {
      queryParams['pageNumber'] = opts.pageNumber
    }
    if (opts.pageSize !== undefined && opts.pageSize !== null) {
      queryParams['pageSize'] = opts.pageSize
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.groupCode !== undefined && opts.groupCode !== null) {
      queryParams['groupCode'] = opts.groupCode
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    if (opts.alarmId !== undefined && opts.alarmId !== null) {
      queryParams['alarmId'] = opts.alarmId
    }
    if (opts.alarming !== undefined && opts.alarming !== null) {
      queryParams['alarming'] = opts.alarming
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      queryParams['startTime'] = opts.startTime
    }
    if (opts.endTime !== undefined && opts.endTime !== null) {
      queryParams['endTime'] = opts.endTime
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      queryParams['ruleType'] = opts.ruleType
    }
    Object.assign(queryParams, this.buildFilterParam(opts.filters, 'filters'))
    Object.assign(
      queryParams,
      this.buildArrayParam(opts.resourceIdList, 'resourceIdList')
    )
    Object.assign(
      queryParams,
      this.buildArrayParam(opts.serviceCodeList, 'serviceCodeList')
    )

    let pathParams = {
      regionId: 'jdcloud'
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeAlarmHistoryAllRegion with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/ruleNoticeHistory',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  删除自定义监控规则
      * @param {Object} opts - parameters
      * @param {string} opts.ids - ids,多个id用|分隔
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      */

  deleteAlarmsCm (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  deleteAlarmsCm"
      )
    }

    opts = opts || {}

    if (opts.ids === undefined || opts.ids === null) {
      throw new Error(
        "Missing the required parameter 'opts.ids' when calling deleteAlarmsCm"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.ids !== undefined && opts.ids !== null) {
      queryParams['ids'] = opts.ids
    }

    let pathParams = {
      regionId: regionId
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call deleteAlarmsCm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/cmAlarms',
      'DELETE',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  根据产品线查询可用监控项列表,metric介绍：&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;Metrics&lt;/a&gt;
      * @param {Object} opts - parameters
      * @param {string} opts.serviceCode - 资源的类型，取值vm, lb, ip, database 等
      * @param {integer} [opts.type] - metric的类型，取值0(控制台展示)、1(内部使用，控制台不展示)、2(所有).默认取0  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param metricDetail metrics
      */

  describeMetrics (opts, callback) {
    opts = opts || {}

    if (opts.serviceCode === undefined || opts.serviceCode === null) {
      throw new Error(
        "Missing the required parameter 'opts.serviceCode' when calling describeMetrics"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.type !== undefined && opts.type !== null) {
      queryParams['type'] = opts.type
    }

    let pathParams = {
      regionId: 'jdcloud'
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeMetrics with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/metrics',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查询可用创建监控规则的指标列表,metric介绍：&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;Metrics&lt;/a&gt;
      * @param {Object} opts - parameters
      * @param {string} [opts.serviceCode] - 资源的类型，取值vm, lb, ip, database 等  optional
      * @param {integer} [opts.type] - metric类型，取值0、1；默认值：0（常规指标，用于控制台创建报警规则）、1（其它）  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param serviceCodeMetrics serviceCodeList
      */

  describeMetricsForCreateAlarm (opts, callback) {
    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.type !== undefined && opts.type !== null) {
      queryParams['type'] = opts.type
    }

    let pathParams = {
      regionId: 'jdcloud'
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeMetricsForCreateAlarm with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/metricsForCreateAlarm',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查看某资源的最后一个点,metric介绍：&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;Metrics&lt;/a&gt;
      * @param {Object} opts - parameters
      * @param {string} opts.metric - 监控项英文标识(id)
      * @param {string} opts.serviceCode - 资源的类型，取值vm, lb, ip, database 等
      * @param {string} opts.resourceId - 资源的uuid，支持多个resourceId批量查询，每个id用竖线分隔。 如：id1|id2|id3|id4
      * @param {string} [opts.startTime] - 查询时间范围的开始时间， UTC时间，格式：2016-12-11T00:00:00+0800（早于30d时，将被重置为30d）（注意在url中+要转译为%2B故url中为2016-12-11T00:00:00%2B0800）  optional
      * @param {string} [opts.endTime] - 查询时间范围的结束时间， UTC时间，格式：2016-12-11T00:00:00+0800（为空时，将由startTime与timeInterval计算得出）（注意在url中+要转译为%2B故url中为2016-12-11T00:00:00%2B0800）  optional
      * @param {string} [opts.timeInterval] - 查询的时间间隔，最大不超过30天，支持分钟级别,小时级别，天级别，例如：1m、1h、1d  optional
      * @param {string} [opts.aggrType] - 聚合方式：max avg min等,用于不同维度之间聚合  optional
      * @param {string} [opts.downAggrType] - 聚合方式：max avg min等,用于将维度内一个周期数据聚合为一个点的聚合方式,默认last  optional
      * @param {tagFilter} [opts.tags] - 自定义标签  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param lastDownsampleRespItem items
      */

  lastDownsample (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  lastDownsample"
      )
    }

    opts = opts || {}

    if (opts.metric === undefined || opts.metric === null) {
      throw new Error(
        "Missing the required parameter 'opts.metric' when calling lastDownsample"
      )
    }
    if (opts.serviceCode === undefined || opts.serviceCode === null) {
      throw new Error(
        "Missing the required parameter 'opts.serviceCode' when calling lastDownsample"
      )
    }
    if (opts.resourceId === undefined || opts.resourceId === null) {
      throw new Error(
        "Missing the required parameter 'opts.resourceId' when calling lastDownsample"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      queryParams['startTime'] = opts.startTime
    }
    if (opts.endTime !== undefined && opts.endTime !== null) {
      queryParams['endTime'] = opts.endTime
    }
    if (opts.timeInterval !== undefined && opts.timeInterval !== null) {
      queryParams['timeInterval'] = opts.timeInterval
    }
    if (opts.aggrType !== undefined && opts.aggrType !== null) {
      queryParams['aggrType'] = opts.aggrType
    }
    if (opts.downAggrType !== undefined && opts.downAggrType !== null) {
      queryParams['downAggrType'] = opts.downAggrType
    }
    Object.assign(queryParams, this.buildTagFilterParam(opts.tags, 'tags'))

    let pathParams = {
      regionId: regionId,
      metric: opts.metric
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call lastDownsample with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/metrics/{metric}/lastDownsample',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  查看某资源多个监控项数据，metric介绍1：&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;Metrics&lt;/a&gt;
      * @param {Object} opts - parameters
      * @param {string} opts.metric - 监控项英文标识(id)
      * @param {string} [opts.aggrType] - 聚合方式，默认等于downSampleType或avg，可选值参考:sum、avg、last、min、max  optional
      * @param {string} [opts.downSampleType] - 采样方式，默认等于aggrType或avg，可选值参考：sum、avg、last、min、max  optional
      * @param {string} [opts.startTime] - 查询时间范围的开始时间， UTC时间，格式：2016-12-11T00:00:00+0800（注意在url中+要转译为%2B故url中为2016-12-11T00:00:00%2B0800）  optional
      * @param {string} [opts.endTime] - 查询时间范围的结束时间， UTC时间，格式：2016-12-11T00:00:00+0800（为空时，将由startTime与timeInterval计算得出）（注意在url中+要转译为%2B故url中为2016-12-11T00:00:00%2B0800）  optional
      * @param {string} [opts.timeInterval] - 时间间隔：1h，6h，12h，1d，3d，7d，14d，固定时间间隔，timeInterval默认为1h，当前时间往 前1h  optional
      * @param {boolean} [opts.groupBy] - 是否对查询的tags分组  optional
      * @param {boolean} [opts.rate] - 是否求速率  optional
      * @param {string} opts.serviceCode - 资源的类型，取值vm, lb, ip, database 等
      * @param {string} opts.resourceId - 资源的uuid
      * @param {tagFilter} [opts.tags] - 监控指标数据的维度信息,根据tags来筛选指标数据不同的维度  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param metricData metricDatas
      */

  describeMetricData (opts, regionId = this.config.regionId, callback) {
    if (typeof regionId === 'function') {
      callback = regionId
      regionId = this.config.regionId
    }

    if (regionId === undefined || regionId === null) {
      throw new Error(
        "Missing the required parameter 'regionId' when calling  describeMetricData"
      )
    }

    opts = opts || {}

    if (opts.metric === undefined || opts.metric === null) {
      throw new Error(
        "Missing the required parameter 'opts.metric' when calling describeMetricData"
      )
    }
    if (opts.serviceCode === undefined || opts.serviceCode === null) {
      throw new Error(
        "Missing the required parameter 'opts.serviceCode' when calling describeMetricData"
      )
    }
    if (opts.resourceId === undefined || opts.resourceId === null) {
      throw new Error(
        "Missing the required parameter 'opts.resourceId' when calling describeMetricData"
      )
    }

    let postBody = null
    let queryParams = {}
    if (opts.aggrType !== undefined && opts.aggrType !== null) {
      queryParams['aggrType'] = opts.aggrType
    }
    if (opts.downSampleType !== undefined && opts.downSampleType !== null) {
      queryParams['downSampleType'] = opts.downSampleType
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      queryParams['startTime'] = opts.startTime
    }
    if (opts.endTime !== undefined && opts.endTime !== null) {
      queryParams['endTime'] = opts.endTime
    }
    if (opts.timeInterval !== undefined && opts.timeInterval !== null) {
      queryParams['timeInterval'] = opts.timeInterval
    }
    if (opts.groupBy !== undefined && opts.groupBy !== null) {
      queryParams['groupBy'] = opts.groupBy
    }
    if (opts.rate !== undefined && opts.rate !== null) {
      queryParams['rate'] = opts.rate
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    Object.assign(queryParams, this.buildTagFilterParam(opts.tags, 'tags'))

    let pathParams = {
      regionId: regionId,
      metric: opts.metric
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeMetricData with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/regions/{regionId}/metrics/{metric}/metricData',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  该接口为自定义监控数据上报的接口，方便您将自己采集的时序数据上报到云监控。不同region域名上报不同region的数据，参考：&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/reporting-monitoring-data&quot;&gt;调用说明&lt;/a&gt;可上报原始数据和已聚合的统计数据。支持批量上报方式。单次请求最多包含 50 个数据点；数据大小不超过 256k。
      * @param {Object} opts - parameters
      * @param {array} [opts.metricDataList] - 数据参数  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param boolean success  全部写入成功为true，否则为false
      * @param metricDataList errMetricDataList
      */

  putMetricData (opts, callback) {
    opts = opts || {}

    let postBody = {}
    if (opts.metricDataList !== undefined && opts.metricDataList !== null) {
      postBody['metricDataList'] = opts.metricDataList
    }

    let queryParams = {}

    let pathParams = {
      regionId: 'jdcloud'
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call putMetricData with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/customMetrics',
      'POST',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }

  /**
      *  概览页产品线信息接口
      * @param {Object} opts - parameters
      * @param {integer} [opts.productType] - 要查询的产品线类型   0：all    1：资源监控   2：其它   默认：1。若指定了查询的serviceCode，则忽略该参数  optional
      * @param {filter} [opts.filters] - 服务码列表
filter name 为serviceCodes表示查询多个产品线的规则  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param serviceInfo services
      */

  describeServices (opts, callback) {
    opts = opts || {}

    let postBody = null
    let queryParams = {}
    if (opts.productType !== undefined && opts.productType !== null) {
      queryParams['productType'] = opts.productType
    }
    Object.assign(queryParams, this.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: 'jdcloud'
    }

    let headerParams = {
      'User-Agent': 'JdcloudSdkNode/1.0.0  monitor/1.3.9'
    }

    let contentTypes = ['application/json']
    let accepts = ['application/json']

    // 扩展自定义头
    if (opts['x-extra-header']) {
      for (let extraHeader in opts['x-extra-header']) {
        headerParams[extraHeader] = opts['x-extra-header'][extraHeader]
      }

      if (Array.isArray(opts['x-extra-header']['content-type'])) {
        contentTypes = opts['x-extra-header']['content-type']
      } else if (typeof opts['x-extra-header']['content-type'] === 'string') {
        contentTypes = opts['x-extra-header']['content-type'].split(',')
      }

      if (Array.isArray(opts['x-extra-header']['accept'])) {
        accepts = opts['x-extra-header']['accept']
      } else if (typeof opts['x-extra-header']['accept'] === 'string') {
        accepts = opts['x-extra-header']['accept'].split(',')
      }
    }

    let formParams = {}

    let returnType = null

    this.config.logger(
      `call describeServices with params:\npathParams:${JSON.stringify(
        pathParams
      )},\nqueryParams:${JSON.stringify(
        queryParams
      )}, \nheaderParams:${JSON.stringify(
        headerParams
      )}, \nformParams:${JSON.stringify(
        formParams
      )}, \npostBody:${JSON.stringify(postBody)}`,
      'DEBUG'
    )

    let request = this.makeRequest(
      '/services',
      'GET',
      pathParams,
      queryParams,
      headerParams,
      formParams,
      postBody,
      contentTypes,
      accepts,
      returnType,
      callback
    )

    return request.then(
      function (result) {
        if (callback && typeof callback === 'function') {
          return callback(null, result)
        }
        return result
      },
      function (error) {
        if (callback && typeof callback === 'function') {
          return callback(error)
        }
        return Promise.reject(error)
      }
    )
  }
}
module.exports = JDCloud.MONITOR
