/*
 * 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.
 *
 * maintainAuxiliaryTags APIs
 * 一组资源增加删除标签
 *
 * OpenAPI spec version: v2
 * 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 2.5.12
 */

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 = '/v2' // 默认要设为空""
    super(serviceId, options)
  }

  /**
      *  查询规则列表
      * @param {Object} opts - parameters
      * @param {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {integer} [opts.dataOwner] - 数据所有者，1云监控控制台; 2云鼎。默认为1  optional
      * @param {string} [opts.serviceCode] - 产品线标识，同一个产品线下可能存在多个product，如(redis下有redis2.8cluster、redis4.0)  optional
      * @param {string} [opts.product] - 产品标识，如redis下分多个产品(redis2.8cluster、redis4.0)。同时指定serviceCode与product时，product优先生效  optional
      * @param {string} [opts.dimension] - 产品下的维度标识，指定dimension时必须指定product  optional
      * @param {string} [opts.ruleName] - 规则名称  optional
      * @param {integer} [opts.ruleType] - 规则类型, 1表示资源监控，6表示站点监控,7表示可用性监控  optional
      * @param {integer} [opts.enabled] - 规则状态：1为启用，0为禁用  optional
      * @param {integer} [opts.ruleStatus] - 资源的规则状态  2：报警、4：数据不足  optional
      * @param {filter} [opts.filters] - 服务码或资源Id列表
products - 产品product，精确匹配，支持多个
resourceIds - 资源Id，精确匹配，支持多个（必须指定serviceCode、product或dimension，否则该参数不生效）
alarmIds - 规则id，精确匹配，支持多个  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param describeGroupAlarm alarmList
      * @param integer numberPages  总页数
      * @param integer numberRecords  总记录数
      * @param integer pageNumber  当前页码
      * @param integer pageSize  分页大小
      */

  describeAlarms (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.dataOwner !== undefined && opts.dataOwner !== null) {
      queryParams['dataOwner'] = opts.dataOwner
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.product !== undefined && opts.product !== null) {
      queryParams['product'] = opts.product
    }
    if (opts.dimension !== undefined && opts.dimension !== null) {
      queryParams['dimension'] = opts.dimension
    }
    if (opts.ruleName !== undefined && opts.ruleName !== null) {
      queryParams['ruleName'] = opts.ruleName
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      queryParams['ruleType'] = opts.ruleType
    }
    if (opts.enabled !== undefined && opts.enabled !== null) {
      queryParams['enabled'] = opts.enabled
    }
    if (opts.ruleStatus !== undefined && opts.ruleStatus !== null) {
      queryParams['ruleStatus'] = opts.ruleStatus
    }
    Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 = super.makeRequest(
      '/groupAlarms',
      '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.autoScalingPolicyId] - 弹性伸缩组Id。注：仅ag\asg产品线内部使用  optional
      * @param {array} [opts.baseContact] - 告警通知联系人  optional
      * @param {string} opts.clientToken - 幂等性校验参数,最长36位,若两个请求clientToken相等，则返回第一次创建的规则id，只创建一次规则
      * @param {integer} [opts.dataOwner] - 数据所有者，1云监控控制台; 2云鼎。默认为1  optional
      * @param {string} [opts.dimension] - 资源维度，可用的维度请使用 describeProductsForAlarm接口查询  optional
      * @param {integer} [opts.enabled] - 是否启用, 1表示启用规则，0表示禁用规则，默认为1  optional
      * @param {array} [opts.multiWebHook] - url回调设置数组  optional
      * @param {array} [opts.noticeOption] - 通知策略  optional
      * @param {string} opts.product - 资源类型, 可用的资源类型列表请使用 describeProductsForAlarm接口查询。
      * @param {resourceOption} opts.resourceOption
      * @param {string} opts.ruleName - 规则名称，规则名称，最大长度42个字符，只允许中英文、数字、&#39;&#39;-&#39;&#39;和&quot;_&quot;
      * @param {ruleOption} opts.ruleOption
      * @param {string} [opts.ruleType] - 规则类型, 默认为resourceMonitor  optional
      * @param {object} [opts.tags] - 资源维度，指定监控数据实例的维度标签,如resourceId&#x3D;id。(请确认资源的监控数据带有该标签，否则规则会报数据不足)  optional
      * @param {webHookOption} [opts.webHookOption]   optional
      * @param {string} callback - callback
      @return {Object} result
      * @param string alarmId  创建成功的规则id
      * @param integer ruleIds
      */

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

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

    let postBody = {}
    if (
      opts.autoScalingPolicyId !== undefined &&
      opts.autoScalingPolicyId !== null
    ) {
      postBody['autoScalingPolicyId'] = opts.autoScalingPolicyId
    }
    if (opts.baseContact !== undefined && opts.baseContact !== null) {
      postBody['baseContact'] = opts.baseContact
    }
    if (opts.clientToken !== undefined && opts.clientToken !== null) {
      postBody['clientToken'] = opts.clientToken
    }
    if (opts.dataOwner !== undefined && opts.dataOwner !== null) {
      postBody['dataOwner'] = opts.dataOwner
    }
    if (opts.dimension !== undefined && opts.dimension !== null) {
      postBody['dimension'] = opts.dimension
    }
    if (opts.enabled !== undefined && opts.enabled !== null) {
      postBody['enabled'] = opts.enabled
    }
    if (opts.multiWebHook !== undefined && opts.multiWebHook !== null) {
      postBody['multiWebHook'] = opts.multiWebHook
    }
    if (opts.noticeOption !== undefined && opts.noticeOption !== null) {
      postBody['noticeOption'] = opts.noticeOption
    }
    if (opts.product !== undefined && opts.product !== null) {
      postBody['product'] = opts.product
    }
    if (opts.resourceOption !== undefined && opts.resourceOption !== null) {
      postBody['resourceOption'] = opts.resourceOption
    }
    if (opts.ruleName !== undefined && opts.ruleName !== null) {
      postBody['ruleName'] = opts.ruleName
    }
    if (opts.ruleOption !== undefined && opts.ruleOption !== null) {
      postBody['ruleOption'] = opts.ruleOption
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      postBody['ruleType'] = opts.ruleType
    }
    if (opts.tags !== undefined && opts.tags !== null) {
      postBody['tags'] = opts.tags
    }
    if (opts.webHookOption !== undefined && opts.webHookOption !== null) {
      postBody['webHookOption'] = opts.webHookOption
    }

    let queryParams = {}

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 = super.makeRequest(
      '/groupAlarms',
      '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} callback - callback
      @return {Object} result
      * @param string alarmId  报警规则ID
      * @param integer alarmStatus  规则状态，当一个规则下同时存在报警、数据不足、正常的资源时，规则状态按 报警&gt;数据不足&gt;正常的优先级展示
监控项状态：-1 未启用 1正常，2告警，4数据不足
      * @param integer alarmStatusList
      * @param baseContact baseContact
      * @param string createTime  创建时间
      * @param string dimension  资源维度
      * @param string dimensionName  资源维度名称
      * @param integer enabled  是否启用, 1表示启用规则，0表示禁用规则，默认为1
      * @param webHookOption multiWebHook
      * @param noticeOption noticeOption
      * @param string product  资源类型
      * @param string productName  资源类型名称
      * @param resourceOption resourceOption
      * @param string ruleName  规则名称，规则名称，最大长度42个字符，只允许中英文、数字、&#39;&#39;-&#39;&#39;和&quot;_&quot;
      * @param ruleOptionDetail ruleOption
      * @param string ruleType  规则类型, 默认为resourceMonitor
      * @param string ruleVersion  规则版本  v1  v2
      * @param object tags  资源维度，指定监控数据实例的维度标签,如resourceId&#x3D;id。(请确认资源的监控数据带有该标签，否则规则会报数据不足)
      * @param webHookOption webHookOption
      */

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

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

    let postBody = null
    let queryParams = {}

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

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

    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 describeAlarm 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 = super.makeRequest(
      '/groupAlarms/{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 {string} [opts.autoScalingPolicyId] - 弹性伸缩组Id。注：仅ag\asg产品线内部使用  optional
      * @param {array} [opts.baseContact] - 告警通知联系人  optional
      * @param {integer} [opts.dataOwner] - 数据所有者，1云监控控制台; 2云鼎。默认为1  optional
      * @param {string} [opts.dimension] - 资源维度，可用的维度请使用 describeProductsForAlarm接口查询  optional
      * @param {integer} [opts.enabled] - 是否启用, 1表示启用规则，0表示禁用规则，默认为1  optional
      * @param {array} [opts.multiWebHook] - url回调设置数组  optional
      * @param {array} [opts.noticeOption] - 通知策略  optional
      * @param {string} opts.product - 资源类型, 可用的资源类型列表请使用 describeProductsForAlarm接口查询。
      * @param {resourceOption} opts.resourceOption
      * @param {string} opts.ruleName - 规则名称，规则名称，最大长度42个字符，只允许中英文、数字、&#39;&#39;-&#39;&#39;和&quot;_&quot;
      * @param {ruleOption} opts.ruleOption
      * @param {string} [opts.ruleType] - 规则类型, 默认为resourceMonitor  optional
      * @param {object} [opts.tags] - 资源维度，指定监控数据实例的维度标签,如resourceId&#x3D;id。(请确认资源的监控数据带有该标签，否则规则会报数据不足)  optional
      * @param {webHookOption} [opts.webHookOption]   optional
      * @param {string} callback - callback
      @return {Object} result
      * @param string alarmId  创建成功的规则id
      * @param integer ruleIds
      * @param boolean success  成功则返回true
      */

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

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

    let postBody = {}
    if (
      opts.autoScalingPolicyId !== undefined &&
      opts.autoScalingPolicyId !== null
    ) {
      postBody['autoScalingPolicyId'] = opts.autoScalingPolicyId
    }
    if (opts.baseContact !== undefined && opts.baseContact !== null) {
      postBody['baseContact'] = opts.baseContact
    }
    if (opts.dataOwner !== undefined && opts.dataOwner !== null) {
      postBody['dataOwner'] = opts.dataOwner
    }
    if (opts.dimension !== undefined && opts.dimension !== null) {
      postBody['dimension'] = opts.dimension
    }
    if (opts.enabled !== undefined && opts.enabled !== null) {
      postBody['enabled'] = opts.enabled
    }
    if (opts.multiWebHook !== undefined && opts.multiWebHook !== null) {
      postBody['multiWebHook'] = opts.multiWebHook
    }
    if (opts.noticeOption !== undefined && opts.noticeOption !== null) {
      postBody['noticeOption'] = opts.noticeOption
    }
    if (opts.product !== undefined && opts.product !== null) {
      postBody['product'] = opts.product
    }
    if (opts.resourceOption !== undefined && opts.resourceOption !== null) {
      postBody['resourceOption'] = opts.resourceOption
    }
    if (opts.ruleName !== undefined && opts.ruleName !== null) {
      postBody['ruleName'] = opts.ruleName
    }
    if (opts.ruleOption !== undefined && opts.ruleOption !== null) {
      postBody['ruleOption'] = opts.ruleOption
    }
    if (opts.ruleType !== undefined && opts.ruleType !== null) {
      postBody['ruleType'] = opts.ruleType
    }
    if (opts.tags !== undefined && opts.tags !== null) {
      postBody['tags'] = opts.tags
    }
    if (opts.webHookOption !== undefined && opts.webHookOption !== null) {
      postBody['webHookOption'] = opts.webHookOption
    }

    let queryParams = {}

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

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

    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 = super.makeRequest(
      '/groupAlarms/{alarmId}',
      'PUT',
      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} callback - callback
      @return {Object} result
      * @param boolean success
      */

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

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

    let postBody = null
    let queryParams = {}

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

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

    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 = super.makeRequest(
      '/groupAlarms/{alarmId}',
      '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 {integer} [opts.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {integer} [opts.referenceType] - 联系人类型。0,联系人分组; 1,联系人  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param describedNoticeContacts contactsList
      * @param integer total  报警联系人总数
      */

  describeAlarmContacts (opts, callback) {
    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: 'jdcloud',
      alarmId: opts.alarmId
    }

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

    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 = super.makeRequest(
      '/groupAlarms/{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)
      }
    )
  }

  /**
      *  查询可用于创建监控规则的指标列表,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] - 产品线  optional
      * @param {string} [opts.product] - 产品类型，如redis2.8cluster(集群)\redis2.8MS(主从)。当serviceCode与product同时指定时，product优先级更高  optional
      * @param {string} [opts.dimension] - 产品维度，必须指定serviceCode或product才生效。  optional
      * @param {integer} [opts.metricType] - metric类型，取值0、1；默认值：0（常规指标，用于控制台创建报警规则）、1（其它）  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param ruleMetricDetail metrics
      */

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

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

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 describeMetricsForAlarm 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 = super.makeRequest(
      '/groupAlarms: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)
      }
    )
  }

  /**
      *  查询可用于创建监控规则的产品列表
      * @param {Object} opts - parameters
      * @param {string} [opts.serviceCode] - 产品线，从产品线维度筛选  optional
      * @param {string} [opts.product] - 产品类型,从产品维度筛选、如redis2.8cluster\redis2.8instance。当serviceCode与product同时指定时，product优先级更高  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param product productList
      */

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

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

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 describeProductsForAlarm 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 = super.makeRequest(
      '/groupAlarms:products',
      '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 {array} [opts.alarmIds] - 告警规则的ID列表  optional
      * @param {integer} [opts.state] - 启用:1,禁用0,  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param boolean success
      */

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

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

    let queryParams = {}

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 enableAlarms 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 = super.makeRequest(
      '/groupAlarms:switch',
      '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.pageNumber] - 当前所在页，默认为1  optional
      * @param {integer} [opts.pageSize] - 页面大小，默认为20；取值范围[1, 100]  optional
      * @param {integer} [opts.dataOwner] - 数据所有者，1云监控控制台; 2云鼎。默认为1  optional
      * @param {string} [opts.serviceCode] - 产品线标识，同一个产品线下可能存在多个product，如(redis下有redis2.8cluster、redis4.0)  optional
      * @param {string} [opts.product] - 产品标识,默认返回该product下所有dimension的数据。eg:product&#x3D;redis2.8cluster（redis2.8cluster产品下包含redis2.8-shard与redis2.8-proxy、redis2.8-instance多个维度)。  optional
      * @param {string} [opts.dimension] - 维度标识、指定该参数时，查询只返回该维度的数据。如redis2.8cluster下存在实例、分片等多个维度  optional
      * @param {string} [opts.region] - 根据region筛选对应region的资源的报警历史  optional
      * @param {integer} [opts.isAlarming] - 正在报警, 取值为1  optional
      * @param {integer} [opts.status] - 报警的状态,1为报警恢复、2为报警、4为报警恢复无数据  optional
      * @param {string} [opts.startTime] - 开始时间  optional
      * @param {string} [opts.endTime] - 结束时间  optional
      * @param {integer} [opts.ruleType] - 规则类型,默认查询1， 1表示资源监控，6表示站点监控,7表示可用性监控  optional
      * @param {string} [opts.ruleName] - 规则名称模糊搜索  optional
      * @param {filter} [opts.filters] - serviceCodes - 产品线servicecode，精确匹配，支持多个
resourceIds - 资源Id，精确匹配，支持多个（必须指定serviceCode才会在该serviceCode下根据resourceIds过滤，否则该参数不生效）
alarmIds - 规则Id，精确匹配，支持多个  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param describedAlarmHistory alarmHistoryList
      * @param integer numberPages  总页数
      * @param integer numberRecords  总记录数
      * @param integer pageNumber  当前页码
      * @param integer pageSize  分页大小
      */

  describeAlarmHistory (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.dataOwner !== undefined && opts.dataOwner !== null) {
      queryParams['dataOwner'] = opts.dataOwner
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      queryParams['serviceCode'] = opts.serviceCode
    }
    if (opts.product !== undefined && opts.product !== null) {
      queryParams['product'] = opts.product
    }
    if (opts.dimension !== undefined && opts.dimension !== null) {
      queryParams['dimension'] = opts.dimension
    }
    if (opts.region !== undefined && opts.region !== null) {
      queryParams['region'] = opts.region
    }
    if (opts.isAlarming !== undefined && opts.isAlarming !== null) {
      queryParams['isAlarming'] = opts.isAlarming
    }
    if (opts.status !== undefined && opts.status !== null) {
      queryParams['status'] = opts.status
    }
    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
    }
    if (opts.ruleName !== undefined && opts.ruleName !== null) {
      queryParams['ruleName'] = opts.ruleName
    }
    Object.assign(queryParams, super.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 = super.makeRequest(
      '/groupAlarmsHistory',
      '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.namespaceUID - namespace
      * @param {string} [opts.endTime] - 查询时间范围的结束时间， UTC时间，格式：2016-12-11T00:00:00+0800（为空时，将由startTime与timeInterval计算得出）  optional
      * @param {queryOption} opts.query
      * @param {string} [opts.startTime] - 查询时间范围的开始时间， UTC时间，格式：2016-12-11T00:00:00+0800  optional
      * @param {string} [opts.timeInterval] - 时间间隔：1h，6h，12h，1d，3d，7d，14d，固定时间间隔，timeInterval默认为1h，当前时间往 前1h  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param metricDataItemCm metricDatas
      */

  describeCustomMetricData (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  describeCustomMetricData"
      )
    }

    opts = opts || {}

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

    let postBody = {}
    if (opts.endTime !== undefined && opts.endTime !== null) {
      postBody['endTime'] = opts.endTime
    }
    if (opts.query !== undefined && opts.query !== null) {
      postBody['query'] = opts.query
    }
    if (opts.startTime !== undefined && opts.startTime !== null) {
      postBody['startTime'] = opts.startTime
    }
    if (opts.timeInterval !== undefined && opts.timeInterval !== null) {
      postBody['timeInterval'] = opts.timeInterval
    }

    let queryParams = {}

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

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

    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 describeCustomMetricData 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 = super.makeRequest(
      '/regions/{regionId}/namespaces/{namespaceUID}/metricData',
      '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)
      }
    )
  }

  /**
      *  根据产品线查询可用监控项列表,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 等。&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/api/describeservices?content&#x3D;API&amp;SOP&#x3D;JDCloud&quot;&gt;describeServices&lt;/a&gt;：查询己接入云监控的产品线列表
      * @param {string} [opts.dimension]   optional
      * @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.dimension !== undefined && opts.dimension !== null) {
      queryParams['dimension'] = opts.dimension
    }
    if (opts.type !== undefined && opts.type !== null) {
      queryParams['type'] = opts.type
    }

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 = super.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的数据聚合为一个点。downAggrType：last(最后一个点)、max(最大值)、min(最小值)、avg(平均值)。该接口返回值为上报metric的原始值，没有做单位转换。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 等。可用的serviceCode请使用describeServices接口查询
      * @param {string} [opts.dimension] - 资源的维度。serviceCode下可用的dimension请使用describeServices接口查询  optional
      * @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 {string} [opts.timeOffset] - 时间偏移，可传入30s、1m、1h、1d等数字+单位的形式(其中s秒，m分，h时，d天)，当业务侧数据上报存在延迟时，可以传入该参数，该参数会使查询的时间段整体向前偏移.偏移后的开始时间若早于30天前,则开始时间自动设置为30天前;若偏移后结束时间早于30天前，则无效  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.dimension !== undefined && opts.dimension !== null) {
      queryParams['dimension'] = opts.dimension
    }
    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
    }
    if (opts.timeOffset !== undefined && opts.timeOffset !== null) {
      queryParams['timeOffset'] = opts.timeOffset
    }
    Object.assign(queryParams, super.buildTagFilterParam(opts.tags, 'tags'))

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

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

    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 = super.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介绍: &lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;Metrics&lt;/a&gt;
可以使用接口:&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/metrics&quot;&gt;describeMetrics&lt;/a&gt;:查询产品线可用的metric列表。
查询起止时间统一向下对齐10s, 举例:开始时间为 08:45:45 会对齐到08:45:40

      * @param {Object} opts - parameters
      * @param {string} opts.metric - 监控项英文标识(id)
      * @param {string} [opts.aggrType] - 聚合方式，用于不同时间轴上的聚合。如balance产品同一个resourceId下存在port&#x3D;80和port&#x3D;8080等多种维度。可选值参考:sum、avg、min、max  optional
      * @param {string} [opts.downSampleType] - 采样方式，用于在时间轴维度上将聚合周期内的数据聚合为一个点。可选值参考：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）
开始时间不得晚于当前时间,开始时间不得早于 30 天前
  optional
      * @param {string} [opts.endTime] - 查询时间范围的结束时间, UTC时间，格式：2016-12-11T00:00:00+0800（为空时，将由startTime与timeInterval计算得出）（注意在url中+要转译为%2B故url中为2016-12-11T00:00:00%2B0800）
默认为当前时间,结束时间不得晚于当前时间. 如果晚于, 会被默认设成当前时间, 结束时间不得早于 30 天前.
  optional
      * @param {string} [opts.timeInterval] - 时间间隔：1h，6h，12h，1d，3d，7d，14d，固定时间间隔，timeInterval默认为1h，当前时间往 前1h
如果指定了 startTime 和 endTime,可以不用设置. 默认的,三个参数都不设置查询 1h 内数据.
timeInterval 默认值 1h
endTime 默认值, 当前时间
startTime 默认值,  endTime - timeInterval
  optional
      * @param {boolean} [opts.groupBy] - 是否对查询的tags分组  optional
      * @param {boolean} [opts.rate] - 是否求速率。仅对累积类型指标有意义, 默认 false  optional
      * @param {string} [opts.serviceCode] - 资源的类型，取值vm, lb, ip, database 等,&lt;a href&#x3D;&quot;https://docs.jdcloud.com/cn/monitoring/api/describeservices?content&#x3D;API&amp;SOP&#x3D;JDCloud&quot;&gt;describeServices&lt;/a&gt;：查询己接入云监控的产品线列表  optional
      * @param {string} [opts.dimension] - 资源的维度。查询serviceCode下可用的维度请使用describeServices接口  optional
      * @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.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.dimension !== undefined && opts.dimension !== null) {
      queryParams['dimension'] = opts.dimension
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      queryParams['resourceId'] = opts.resourceId
    }
    Object.assign(queryParams, super.buildTagFilterParam(opts.tags, 'tags'))

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

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

    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 = super.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)
      }
    )
  }

  /**
      *  查询某资源下指定tag key的tag value
      * @param {Object} opts - parameters
      * @param {string} opts.tagKey - region
      * @param {string} opts.serviceCode - serviceCode
      * @param {string} opts.resourceId - 资源标识
      * @param {string} [opts.metric] - metric  optional
      * @param {string} [opts.startTime] - 查询时间范围的开始时间(如不传,则默认为1时前)， UTC时间，格式：2016-12-11T00:00:00+0800（注意在url中+,:要转译,如2019-10-23T10%3A33%3A31%2B0800）。对于非连续的时序数据，开始时间无法保证准确性  optional
      * @param {string} [opts.endTime] - 查询时间范围的结束时间(如不传,则默认为当前)， UTC时间，格式：2016-12-11T00:00:00+0800（注意在url中+,:要转译,如2019-10-23T10%3A33%3A31%2B0800）.对于非连续的时序数据，结束时间无法保证准确性  optional
      * @param {string} [opts.timeInterval] - 时间间隔：1h，6h，12h，1d，3d，7d，14d，固定时间间隔，timeInterval默认为1h，当前时间往 前1h  optional
      * @param {tagFilter} [opts.tags] - 根据tags进行筛选(传入*和不传的效果一致)  optional
      * @param {string} regionId - ID of the region
      * @param {string} callback - callback
      @return {Object} result
      * @param string tagValues
      */

  describeTagValues (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  describeTagValues"
      )
    }

    opts = opts || {}

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

    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.metric !== undefined && opts.metric !== null) {
      queryParams['metric'] = opts.metric
    }
    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
    }
    Object.assign(queryParams, super.buildTagFilterParam(opts.tags, 'tags'))

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

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

    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 describeTagValues 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 = super.makeRequest(
      '/regions/{regionId}/tagValues/{tagKey}',
      '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 {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 serviceInfoV2 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, super.buildFilterParam(opts.filters, 'filters'))

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 = super.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)
      }
    )
  }

  /**
      *  该接口为自定义监控数据上报的接口，方便您将自己采集的时序数据上报到云监控。不同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/2.5.12'
    }

    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 = super.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)
      }
    )
  }

  /**
      *  该接口为自定义监控数据上报的接口，方便您将自己采集的时序数据上报到云监控。不同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
      */

  putCustomMetricData (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/2.5.12'
    }

    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 putCustomMetricData 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 = super.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 {string} opts.appCode - 目前统一用jcloud
      * @param {string} opts.serviceCode - 资源的类型，取值vm,ip,database,storage,disk,cdn,redis,balance,nat_gw,db_ro,vpn,ddos等,新接入的产品要求与opentapi命名的产品线名称一致
      * @param {string} opts.region - 地域信息，如 cn-north-1 等
      * @param {string} opts.resourceId - 资源的唯一表示，一般为uuid
      * @param {array} [opts.dataPoints] - 监控数据点  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param integer failed  失败数量
      * @param integer success  成功数量
      */

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

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

    let postBody = {}
    if (opts.appCode !== undefined && opts.appCode !== null) {
      postBody['appCode'] = opts.appCode
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      postBody['serviceCode'] = opts.serviceCode
    }
    if (opts.region !== undefined && opts.region !== null) {
      postBody['region'] = opts.region
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      postBody['resourceId'] = opts.resourceId
    }
    if (opts.dataPoints !== undefined && opts.dataPoints !== null) {
      postBody['dataPoints'] = opts.dataPoints
    }

    let queryParams = {}

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 put 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 = super.makeRequest(
      '/put',
      '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.appCode - 目前统一用jcloud
      * @param {string} opts.serviceCode - 资源的类型，取值vm,ip,database,storage,disk,cdn,redis,balance,nat_gw,db_ro,vpn,ddos等,新接入的产品要求与opentapi命名的产品线名称一致
      * @param {string} opts.region - 地域信息，如 cn-north-1 等
      * @param {string} opts.resourceId - 资源的唯一表示，一般为uuid
      * @param {array} [opts.dataPoints] - 监控数据点  optional
      * @param {string} callback - callback
      @return {Object} result
      * @param integer failed  失败数量
      * @param integer success  成功数量
      */

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

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

    let postBody = {}
    if (opts.appCode !== undefined && opts.appCode !== null) {
      postBody['appCode'] = opts.appCode
    }
    if (opts.serviceCode !== undefined && opts.serviceCode !== null) {
      postBody['serviceCode'] = opts.serviceCode
    }
    if (opts.region !== undefined && opts.region !== null) {
      postBody['region'] = opts.region
    }
    if (opts.resourceId !== undefined && opts.resourceId !== null) {
      postBody['resourceId'] = opts.resourceId
    }
    if (opts.dataPoints !== undefined && opts.dataPoints !== null) {
      postBody['dataPoints'] = opts.dataPoints
    }

    let queryParams = {}

    let pathParams = {
      regionId: 'jdcloud'
    }

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

    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 putProductMetricData 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 = super.makeRequest(
      '/put',
      '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)
      }
    )
  }
}
module.exports = MONITOR
