text:
ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}

DOCUMENTATION = '''
---
module: ce_bgp_neighbor
version_added: "2.4"
short_description: Manages BGP peer configuration on HUAWEI CloudEngine switches.
description:
    - Manages BGP peer configurations on HUAWEI CloudEngine switches.
author:
    - wangdezhuang (@QijunPan)
options:
    state:
        description:
            - Specify desired state of the resource.
        default: present
        choices: ['present','absent']
    vrf_name:
        description:
            - Name of a BGP instance. The name is a case-sensitive string of characters.
              The BGP instance can be used only after the corresponding VPN instance is created.
        required: true
    peer_addr:
        description:
            - Connection address of a peer, which can be an IPv4 or IPv6 address.
        required: true
    remote_as:
        description:
            - AS number of a peer.
              The value is a string of 1 to 11 characters.
        required: true
    description:
        description:
            - Description of a peer, which can be letters or digits.
              The value is a string of 1 to 80 characters.
    fake_as:
        description:
            - Fake AS number that is specified for a local peer.
              The value is a string of 1 to 11 characters.
    dual_as:
        description:
            - If the value is true, the EBGP peer can use either a fake AS number or the actual AS number.
              If the value is false, the EBGP peer can only use a fake AS number.
        choices: ['no_use','true','false']
        default: no_use
    conventional:
        description:
            - If the value is true, the router has all extended capabilities.
              If the value is false, the router does not have all extended capabilities.
        choices: ['no_use','true','false']
        default: no_use
    route_refresh:
        description:
            - If the value is true, BGP is enabled to advertise REFRESH packets.
              If the value is false, the route refresh function is enabled.
        choices: ['no_use','true','false']
        default: no_use
    is_ignore:
        description:
            - If the value is true, the session with a specified peer is torn down and all related
              routing entries are cleared.
              If the value is false, the session with a specified peer is retained.
        choices: ['no_use','true','false']
        default: no_use
    local_if_name:
        description:
            - Name of a source interface that sends BGP packets.
              The value is a string of 1 to 63 characters.
    ebgp_max_hop:
        description:
            - Maximum number of hops in an indirect EBGP connection.
              The value is an ranging from 1 to 255.
    valid_ttl_hops:
        description:
            - Enable GTSM on a peer or peer group.
              The valid-TTL-Value parameter is used to specify the number of TTL hops to be detected.
              The value is an integer ranging from 1 to 255.
    connect_mode:
        description:
            - The value can be Connect-only, Listen-only, or Both.
    is_log_change:
        description:
            - If the value is true, BGP is enabled to record peer session status and event information.
              If the value is false, BGP is disabled from recording peer session status and event information.
        choices: ['no_use','true','false']
        default: no_use
    pswd_type:
        description:
            - Enable BGP peers to establish a TCP connection and perform the Message Digest 5 (MD5)
              authentication for BGP messages.
        choices: ['null','cipher','simple']
    pswd_cipher_text:
        description:
            - The character string in a password identifies the contents of the password, spaces not supported.
              The value is a string of 1 to 255 characters.
    keep_alive_time:
        description:
            - Specify the Keepalive time of a peer or peer group.
              The value is an integer ranging from 0 to 21845. The default value is 60.
    hold_time:
        description:
            - Specify the Hold time of a peer or peer group.
              The value is 0 or an integer ranging from 3 to 65535.
    min_hold_time:
        description:
            - Specify the Min hold time of a peer or peer group.
    key_chain_name:
        description:
            - Specify the Keychain authentication name used when BGP peers establish a TCP connection.
              The value is a string of 1 to 47 case-insensitive characters.
    conn_retry_time:
        description:
            - ConnectRetry interval.
              The value is an integer ranging from 1 to 65535.
    tcp_MSS:
        description:
            - Maximum TCP MSS value used for TCP connection establishment for a peer.
              The value is an integer ranging from 176 to 4096.
    mpls_local_ifnet_disable:
        description:
            - If the value is true, peer create MPLS Local IFNET disable.
              If the value is false, peer create MPLS Local IFNET enable.
        choices: ['no_use','true','false']
        default: no_use
    prepend_global_as:
        description:
            - Add the global AS number to the Update packets to be advertised.
        choices: ['no_use','true','false']
        default: no_use
    prepend_fake_as:
        description:
            - Add the Fake AS number to received Update packets.
        choices: ['no_use','true','false']
        default: no_use
    is_bfd_block:
        description:
            - If the value is true, peers are enabled to inherit the BFD function from the peer group.
              If the value is false, peers are disabled to inherit the BFD function from the peer group.
        choices: ['no_use','true','false']
        default: no_use
    multiplier:
        description:
            - Specify the detection multiplier. The default value is 3.
              The value is an integer ranging from 3 to 50.
    is_bfd_enable:
        description:
            - If the value is true, BFD is enabled.
              If the value is false, BFD is disabled.
        choices: ['no_use','true','false']
        default: no_use
    rx_interval:
        description:
            - Specify the minimum interval at which BFD packets are received.
              The value is an integer ranging from 50 to 1000, in milliseconds.
    tx_interval:
        description:
            - Specify the minimum interval at which BFD packets are sent.
              The value is an integer ranging from 50 to 1000, in milliseconds.
    is_single_hop:
        description:
            - If the value is true, the system is enabled to preferentially use the single-hop mode for
              BFD session setup between IBGP peers.
              If the value is false, the system is disabled from preferentially using the single-hop
              mode for BFD session setup between IBGP peers.
        choices: ['no_use','true','false']
        default: no_use
'''

EXAMPLES = '''

- name: CloudEngine BGP neighbor test
  hosts: cloudengine
  connection: local
  gather_facts: no
  vars:
    cli:
      host: "{{ inventory_hostname }}"
      port: "{{ ansible_ssh_port }}"
      username: "{{ username }}"
      password: "{{ password }}"
      transport: cli

  tasks:

  - name: "Config bgp peer"
    ce_bgp_neighbor:
      state: present
      vrf_name: js
      peer_addr: 192.168.10.10
      remote_as: 500
      provider: "{{ cli }}"

  - name: "Config bgp route id"
    ce_bgp_neighbor:
      state: absent
      vrf_name: js
      peer_addr: 192.168.10.10
      provider: "{{ cli }}"
'''

RETURN = '''
changed:
    description: check to see if a change was made on the device
    returned: always
    type: bool
    sample: true
proposed:
    description: k/v pairs of parameters passed into module
    returned: always
    type: dict
    sample: {"peer_addr": "192.168.10.10", "remote_as": "500", "state": "present", "vrf_name": "js"}
existing:
    description: k/v pairs of existing aaa server
    returned: always
    type: dict
    sample: {"bgp peer": []}
end_state:
    description: k/v pairs of aaa params after module execution
    returned: always
    type: dict
    sample: {"bgp peer": [["192.168.10.10", "500"]]}
updates:
    description: command sent to the device
    returned: always
    type: list
    sample: ["peer 192.168.10.10 as-number 500"]
'''

import re
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.cloudengine.ce import get_nc_config, set_nc_config, ce_argument_spec, check_ip_addr

# get bgp peer
CE_GET_BGP_PEER_HEADER = """
    <filter type="subtree">
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer>
                  <peerAddr></peerAddr>
"""
CE_GET_BGP_PEER_TAIL = """
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </filter>
"""

# merge bgp peer
CE_MERGE_BGP_PEER_HEADER = """
    <config>
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer operation="merge">
                  <peerAddr>%s</peerAddr>
"""
CE_MERGE_BGP_PEER_TAIL = """
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </config>
"""

# create bgp peer
CE_CREATE_BGP_PEER_HEADER = """
    <config>
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer operation="create">
                  <peerAddr>%s</peerAddr>
"""
CE_CREATE_BGP_PEER_TAIL = """
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </config>
"""

# delete bgp peer
CE_DELETE_BGP_PEER_HEADER = """
    <config>
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer operation="delete">
                  <peerAddr>%s</peerAddr>
"""
CE_DELETE_BGP_PEER_TAIL = """
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </config>
"""

# get peer bfd
CE_GET_PEER_BFD_HEADER = """
    <filter type="subtree">
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer>
                  <peerAddr>%s</peerAddr>
                  <peerBfd>
"""
CE_GET_PEER_BFD_TAIL = """
                  </peerBfd>
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </filter>
"""

# merge peer bfd
CE_MERGE_PEER_BFD_HEADER = """
    <config>
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer>
                  <peerAddr>%s</peerAddr>
                  <peerBfd operation="merge">
"""
CE_MERGE_PEER_BFD_TAIL = """
                  </peerBfd>
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </config>
"""

# delete peer bfd
CE_DELETE_PEER_BFD_HEADER = """
    <config>
      <bgp xmlns="http://www.huawei.com/netconf/vrp" content-version="1.0" format-version="1.0">
        <bgpcomm>
          <bgpVrfs>
            <bgpVrf>
              <vrfName>%s</vrfName>
              <bgpPeers>
                <bgpPeer>
                  <peerAddr>%s</peerAddr>
                  <peerBfd operation="delete">
"""
CE_DELETE_PEER_BFD_TAIL = """
                  </peerBfd>
                </bgpPeer>
              </bgpPeers>
            </bgpVrf>
          </bgpVrfs>
        </bgpcomm>
      </bgp>
    </config>
"""

class BgpNeighbor(object):
    """ Manages BGP peer configuration """

    def netconf_get_config(self, **kwargs):
        """ netconf_get_config """

        module = kwargs["module"]
        conf_str = kwargs["conf_str"]

        xml_str = get_nc_config(module, conf_str)

        return xml_str

    def netconf_set_config(self, **kwargs):
        """ netconf_set_config """

        module = kwargs["module"]
        conf_str = kwargs["conf_str"]

        xml_str = set_nc_config(module, conf_str)

        return xml_str

    def check_bgp_peer_args(self, **kwargs):
        """ check_bgp_peer_args """

        module = kwargs["module"]
        result = dict()
        need_cfg = False

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        peer_addr = module.params['peer_addr']
        if peer_addr:
            if not check_ip_addr(ipaddr=peer_addr):
                module.fail_json(
                    msg='Error: The peer_addr %s is invalid.' % peer_addr)

            need_cfg = True

        remote_as = module.params['remote_as']
        if remote_as:
            if len(remote_as) > 11 or len(remote_as) < 1:
                module.fail_json(
                    msg='Error: The len of remote_as %s is out of [1 - 11].' % remote_as)

            need_cfg = True

        result["need_cfg"] = need_cfg
        return result

    def check_bgp_peer_other_args(self, **kwargs):
        """ check_bgp_peer_other_args """

        module = kwargs["module"]
        result = dict()
        need_cfg = False

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        description = module.params['description']
        if description:
            if len(description) > 80 or len(description) < 1:
                module.fail_json(
                    msg='Error: The len of description %s is out of [1 - 80].' % description)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<description></description>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<description>(.*)</description>.*', recv_xml)

                if re_find:
                    result["description"] = re_find
                    if re_find[0] != description:
                        need_cfg = True
                else:
                    need_cfg = True

        fake_as = module.params['fake_as']
        if fake_as:
            if len(fake_as) > 11 or len(fake_as) < 1:
                module.fail_json(
                    msg='Error: The len of fake_as %s is out of [1 - 11].' % fake_as)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<fakeAs></fakeAs>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<fakeAs>(.*)</fakeAs>.*', recv_xml)

                if re_find:
                    result["fake_as"] = re_find
                    if re_find[0] != fake_as:
                        need_cfg = True
                else:
                    need_cfg = True

        dual_as = module.params['dual_as']
        if dual_as != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<dualAs></dualAs>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<dualAs>(.*)</dualAs>.*', recv_xml)

                if re_find:
                    result["dual_as"] = re_find
                    if re_find[0] != fake_as:
                        need_cfg = True
                else:
                    need_cfg = True

        conventional = module.params['conventional']
        if conventional != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<conventional></conventional>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<conventional>(.*)</conventional>.*', recv_xml)

                if re_find:
                    result["conventional"] = re_find
                    if re_find[0] != conventional:
                        need_cfg = True
                else:
                    need_cfg = True

        route_refresh = module.params['route_refresh']
        if route_refresh != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<routeRefresh></routeRefresh>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<routeRefresh>(.*)</routeRefresh>.*', recv_xml)

                if re_find:
                    result["route_refresh"] = re_find
                    if re_find[0] != route_refresh:
                        need_cfg = True
                else:
                    need_cfg = True

        four_byte_as = module.params['four_byte_as']
        if four_byte_as != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<fourByteAs></fourByteAs>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<fourByteAs>(.*)</fourByteAs>.*', recv_xml)

                if re_find:
                    result["four_byte_as"] = re_find
                    if re_find[0] != four_byte_as:
                        need_cfg = True
                else:
                    need_cfg = True

        is_ignore = module.params['is_ignore']
        if is_ignore != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<isIgnore></isIgnore>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<isIgnore>(.*)</isIgnore>.*', recv_xml)

                if re_find:
                    result["is_ignore"] = re_find
                    if re_find[0] != is_ignore:
                        need_cfg = True
                else:
                    need_cfg = True

        local_if_name = module.params['local_if_name']
        if local_if_name:
            if len(local_if_name) > 63 or len(local_if_name) < 1:
                module.fail_json(
                    msg='Error: The len of local_if_name %s is out of [1 - 63].' % local_if_name)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<localIfName></localIfName>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<localIfName>(.*)</localIfName>.*', recv_xml)

                if re_find:
                    result["local_if_name"] = re_find
                    if re_find[0] != local_if_name:
                        need_cfg = True
                else:
                    need_cfg = True

        ebgp_max_hop = module.params['ebgp_max_hop']
        if ebgp_max_hop:
            if int(ebgp_max_hop) > 255 or int(ebgp_max_hop) < 1:
                module.fail_json(
                    msg='Error: The value of ebgp_max_hop %s is out of [1 - 255].' % ebgp_max_hop)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<ebgpMaxHop></ebgpMaxHop>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<ebgpMaxHop>(.*)</ebgpMaxHop>.*', recv_xml)

                if re_find:
                    result["ebgp_max_hop"] = re_find
                    if re_find[0] != ebgp_max_hop:
                        need_cfg = True
                else:
                    need_cfg = True

        valid_ttl_hops = module.params['valid_ttl_hops']
        if valid_ttl_hops:
            if int(valid_ttl_hops) > 255 or int(valid_ttl_hops) < 1:
                module.fail_json(
                    msg='Error: The value of valid_ttl_hops %s is out of [1 - 255].' % valid_ttl_hops)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<validTtlHops></validTtlHops>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<validTtlHops>(.*)</validTtlHops>.*', recv_xml)

                if re_find:
                    result["valid_ttl_hops"] = re_find
                    if re_find[0] != valid_ttl_hops:
                        need_cfg = True
                else:
                    need_cfg = True

        connect_mode = module.params['connect_mode']
        if connect_mode:

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<connectMode></connectMode>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<connectMode>(.*)</connectMode>.*', recv_xml)

                if re_find:
                    result["connect_mode"] = re_find
                    if re_find[0] != connect_mode:
                        need_cfg = True
                else:
                    need_cfg = True

        is_log_change = module.params['is_log_change']
        if is_log_change != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<isLogChange></isLogChange>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<isLogChange>(.*)</isLogChange>.*', recv_xml)

                if re_find:
                    result["is_log_change"] = re_find
                    if re_find[0] != is_log_change:
                        need_cfg = True
                else:
                    need_cfg = True

        pswd_type = module.params['pswd_type']
        if pswd_type:

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<pswdType></pswdType>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<pswdType>(.*)</pswdType>.*', recv_xml)

                if re_find:
                    result["pswd_type"] = re_find
                    if re_find[0] != pswd_type:
                        need_cfg = True
                else:
                    need_cfg = True

        pswd_cipher_text = module.params['pswd_cipher_text']
        if pswd_cipher_text:
            if len(pswd_cipher_text) > 255 or len(pswd_cipher_text) < 1:
                module.fail_json(
                    msg='Error: The len of pswd_cipher_text %s is out of [1 - 255].' % pswd_cipher_text)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<pswdCipherText></pswdCipherText>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<pswdCipherText>(.*)</pswdCipherText>.*', recv_xml)

                if re_find:
                    result["pswd_cipher_text"] = re_find
                    if re_find[0] != pswd_cipher_text:
                        need_cfg = True
                else:
                    need_cfg = True

        keep_alive_time = module.params['keep_alive_time']
        if keep_alive_time:
            if int(keep_alive_time) > 21845 or len(keep_alive_time) < 0:
                module.fail_json(
                    msg='Error: The len of keep_alive_time %s is out of [0 - 21845].' % keep_alive_time)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<keepAliveTime></keepAliveTime>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<keepAliveTime>(.*)</keepAliveTime>.*', recv_xml)

                if re_find:
                    result["keep_alive_time"] = re_find
                    if re_find[0] != keep_alive_time:
                        need_cfg = True
                else:
                    need_cfg = True

        hold_time = module.params['hold_time']
        if hold_time:
            if int(hold_time) != 0 and (int(hold_time) > 65535 or int(hold_time) < 3):
                module.fail_json(
                    msg='Error: The value of hold_time %s is out of [0 or 3 - 65535].' % hold_time)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<holdTime></holdTime>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<holdTime>(.*)</holdTime>.*', recv_xml)

                if re_find:
                    result["hold_time"] = re_find
                    if re_find[0] != hold_time:
                        need_cfg = True
                else:
                    need_cfg = True

        min_hold_time = module.params['min_hold_time']
        if min_hold_time:
            if int(min_hold_time) != 0 and (int(min_hold_time) > 65535 or int(min_hold_time) < 20):
                module.fail_json(
                    msg='Error: The value of min_hold_time %s is out of [0 or 20 - 65535].' % min_hold_time)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<minHoldTime></minHoldTime>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<minHoldTime>(.*)</minHoldTime>.*', recv_xml)

                if re_find:
                    result["min_hold_time"] = re_find
                    if re_find[0] != min_hold_time:
                        need_cfg = True
                else:
                    need_cfg = True

        key_chain_name = module.params['key_chain_name']
        if key_chain_name:
            if len(key_chain_name) > 47 or len(key_chain_name) < 1:
                module.fail_json(
                    msg='Error: The len of key_chain_name %s is out of [1 - 47].' % key_chain_name)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<keyChainName></keyChainName>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<keyChainName>(.*)</keyChainName>.*', recv_xml)

                if re_find:
                    result["key_chain_name"] = re_find
                    if re_find[0] != key_chain_name:
                        need_cfg = True
                else:
                    need_cfg = True

        conn_retry_time = module.params['conn_retry_time']
        if conn_retry_time:
            if int(conn_retry_time) > 65535 or int(conn_retry_time) < 1:
                module.fail_json(
                    msg='Error: The value of conn_retry_time %s is out of [1 - 65535].' % conn_retry_time)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<connRetryTime></connRetryTime>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<connRetryTime>(.*)</connRetryTime>.*', recv_xml)

                if re_find:
                    result["conn_retry_time"] = re_find
                    if re_find[0] != conn_retry_time:
                        need_cfg = True
                else:
                    need_cfg = True

        tcp_mss = module.params['tcp_MSS']
        if tcp_mss:
            if int(tcp_mss) > 4096 or int(tcp_mss) < 176:
                module.fail_json(
                    msg='Error: The value of tcp_mss %s is out of [176 - 4096].' % tcp_mss)

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<tcpMSS></tcpMSS>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<tcpMSS>(.*)</tcpMSS>.*', recv_xml)

                if re_find:
                    result["tcp_MSS"] = re_find
                    if re_find[0] != tcp_mss:
                        need_cfg = True
                else:
                    need_cfg = True

        mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
        if mpls_local_ifnet_disable != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<mplsLocalIfnetDisable></mplsLocalIfnetDisable>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<mplsLocalIfnetDisable>(.*)</mplsLocalIfnetDisable>.*', recv_xml)

                if re_find:
                    result["mpls_local_ifnet_disable"] = re_find
                    if re_find[0] != mpls_local_ifnet_disable:
                        need_cfg = True
                else:
                    need_cfg = True

        prepend_global_as = module.params['prepend_global_as']
        if prepend_global_as != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<prependGlobalAs></prependGlobalAs>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<prependGlobalAs>(.*)</prependGlobalAs>.*', recv_xml)

                if re_find:
                    result["prepend_global_as"] = re_find
                    if re_find[0] != prepend_global_as:
                        need_cfg = True
                else:
                    need_cfg = True

        prepend_fake_as = module.params['prepend_fake_as']
        if prepend_fake_as != 'no_use':

            conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
                "<prependFakeAs></prependFakeAs>" + CE_GET_BGP_PEER_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<prependFakeAs>(.*)</prependFakeAs>.*', recv_xml)

                if re_find:
                    result["prepend_fake_as"] = re_find
                    if re_find[0] != prepend_fake_as:
                        need_cfg = True
                else:
                    need_cfg = True

        result["need_cfg"] = need_cfg
        return result

    def check_peer_bfd_merge_args(self, **kwargs):
        """ check_peer_bfd_merge_args """

        module = kwargs["module"]
        result = dict()
        need_cfg = False

        state = module.params['state']
        if state == "absent":
            result["need_cfg"] = need_cfg
            return result

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        peer_addr = module.params['peer_addr']

        is_bfd_block = module.params['is_bfd_block']
        if is_bfd_block != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isBfdBlock></isBfdBlock>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<isBfdBlock>(.*)</isBfdBlock>.*', recv_xml)

                if re_find:
                    result["is_bfd_block"] = re_find
                    if re_find[0] != is_bfd_block:
                        need_cfg = True
                else:
                    need_cfg = True

        multiplier = module.params['multiplier']
        if multiplier:
            if int(multiplier) > 50 or int(multiplier) < 3:
                module.fail_json(
                    msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<multiplier></multiplier>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<multiplier>(.*)</multiplier>.*', recv_xml)

                if re_find:
                    result["multiplier"] = re_find
                    if re_find[0] != multiplier:
                        need_cfg = True
                else:
                    need_cfg = True

        is_bfd_enable = module.params['is_bfd_enable']
        if is_bfd_enable != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isBfdEnable></isBfdEnable>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<isBfdEnable>(.*)</isBfdEnable>.*', recv_xml)

                if re_find:
                    result["is_bfd_enable"] = re_find
                    if re_find[0] != is_bfd_enable:
                        need_cfg = True
                else:
                    need_cfg = True

        rx_interval = module.params['rx_interval']
        if rx_interval:
            if int(rx_interval) > 1000 or int(rx_interval) < 50:
                module.fail_json(
                    msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<rxInterval></rxInterval>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<rxInterval>(.*)</rxInterval>.*', recv_xml)

                if re_find:
                    result["rx_interval"] = re_find
                    if re_find[0] != rx_interval:
                        need_cfg = True
                else:
                    need_cfg = True

        tx_interval = module.params['tx_interval']
        if tx_interval:
            if int(tx_interval) > 1000 or int(tx_interval) < 50:
                module.fail_json(
                    msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<txInterval></txInterval>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<txInterval>(.*)</txInterval>.*', recv_xml)

                if re_find:
                    result["tx_interval"] = re_find
                    if re_find[0] != tx_interval:
                        need_cfg = True
                else:
                    need_cfg = True

        is_single_hop = module.params['is_single_hop']
        if is_single_hop != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isSingleHop></isSingleHop>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                need_cfg = True
            else:
                re_find = re.findall(
                    r'.*<isSingleHop>(.*)</isSingleHop>.*', recv_xml)

                if re_find:
                    result["is_single_hop"] = re_find
                    if re_find[0] != is_single_hop:
                        need_cfg = True
                else:
                    need_cfg = True

        result["need_cfg"] = need_cfg
        return result

    def check_peer_bfd_delete_args(self, **kwargs):
        """ check_peer_bfd_delete_args """

        module = kwargs["module"]
        result = dict()
        need_cfg = False

        state = module.params['state']
        if state == "present":
            result["need_cfg"] = need_cfg
            return result

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        peer_addr = module.params['peer_addr']

        is_bfd_block = module.params['is_bfd_block']
        if is_bfd_block != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isBfdBlock></isBfdBlock>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<isBfdBlock>(.*)</isBfdBlock>.*', recv_xml)

                if re_find:
                    result["is_bfd_block"] = re_find
                    if re_find[0] == is_bfd_block:
                        need_cfg = True

        multiplier = module.params['multiplier']
        if multiplier:
            if int(multiplier) > 50 or int(multiplier) < 3:
                module.fail_json(
                    msg='Error: The value of multiplier %s is out of [3 - 50].' % multiplier)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<multiplier></multiplier>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<multiplier>(.*)</multiplier>.*', recv_xml)

                if re_find:
                    result["multiplier"] = re_find
                    if re_find[0] == multiplier:
                        need_cfg = True

        is_bfd_enable = module.params['is_bfd_enable']
        if is_bfd_enable != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isBfdEnable></isBfdEnable>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<isBfdEnable>(.*)</isBfdEnable>.*', recv_xml)

                if re_find:
                    result["is_bfd_enable"] = re_find
                    if re_find[0] == is_bfd_enable:
                        need_cfg = True

        rx_interval = module.params['rx_interval']
        if rx_interval:
            if int(rx_interval) > 1000 or int(rx_interval) < 50:
                module.fail_json(
                    msg='Error: The value of rx_interval %s is out of [50 - 1000].' % rx_interval)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<rxInterval></rxInterval>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<rxInterval>(.*)</rxInterval>.*', recv_xml)

                if re_find:
                    result["rx_interval"] = re_find
                    if re_find[0] == rx_interval:
                        need_cfg = True

        tx_interval = module.params['tx_interval']
        if tx_interval:
            if int(tx_interval) > 1000 or int(tx_interval) < 50:
                module.fail_json(
                    msg='Error: The value of tx_interval %s is out of [50 - 1000].' % tx_interval)

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<txInterval></txInterval>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<txInterval>(.*)</txInterval>.*', recv_xml)

                if re_find:
                    result["tx_interval"] = re_find
                    if re_find[0] == tx_interval:
                        need_cfg = True

        is_single_hop = module.params['is_single_hop']
        if is_single_hop != 'no_use':

            conf_str = CE_GET_PEER_BFD_HEADER % (
                vrf_name, peer_addr) + "<isSingleHop></isSingleHop>" + CE_GET_PEER_BFD_TAIL
            recv_xml = self.netconf_get_config(module=module, conf_str=conf_str)

            if "<data/>" in recv_xml:
                pass
            else:
                re_find = re.findall(
                    r'.*<isSingleHop>(.*)</isSingleHop>.*', recv_xml)

                if re_find:
                    result["is_single_hop"] = re_find
                    if re_find[0] == is_single_hop:
                        need_cfg = True

        result["need_cfg"] = need_cfg
        return result

    def get_bgp_peer(self, **kwargs):
        """ get_bgp_peer """

        module = kwargs["module"]

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + \
            "<remoteAs></remoteAs>" + CE_GET_BGP_PEER_TAIL

        xml_str = self.netconf_get_config(module=module, conf_str=conf_str)

        result = list()

        if "<data/>" in xml_str:
            return result
        else:
            re_find = re.findall(
                r'.*<peerAddr>(.*)</peerAddr>.*\s.*<remoteAs>(.*)</remoteAs>.*', xml_str)

            if re_find:
                return re_find
            else:
                return result

    def get_bgp_del_peer(self, **kwargs):
        """ get_bgp_del_peer """

        module = kwargs["module"]

        vrf_name = module.params['vrf_name']
        if vrf_name:
            if len(vrf_name) > 31 or len(vrf_name) == 0:
                module.fail_json(
                    msg='Error: The len of vrf_name %s is out of [1 - 31].' % vrf_name)

        conf_str = CE_GET_BGP_PEER_HEADER % vrf_name + CE_GET_BGP_PEER_TAIL

        xml_str = self.netconf_get_config(module=module, conf_str=conf_str)

        result = list()

        if "<data/>" in xml_str:
            return result
        else:
            re_find = re.findall(
                r'.*<peerAddr>(.*)</peerAddr>.*', xml_str)

            if re_find:
                return re_find
            else:
                return result

    def merge_bgp_peer(self, **kwargs):
        """ merge_bgp_peer """

        module = kwargs["module"]
        vrf_name = module.params['vrf_name']
        peer_addr = module.params['peer_addr']
        remote_as = module.params['remote_as']

        conf_str = CE_MERGE_BGP_PEER_HEADER % (
            vrf_name, peer_addr) + "<remoteAs>%s</remoteAs>" % remote_as + CE_MERGE_BGP_PEER_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Merge bgp peer failed.')

        cmds = []
        cmd = "peer %s as-number %s" % (peer_addr, remote_as)
        cmds.append(cmd)

        return cmds

    def create_bgp_peer(self, **kwargs):
        """ create_bgp_peer """

        module = kwargs["module"]

        vrf_name = module.params['vrf_name']

        peer_addr = module.params['peer_addr']
        remote_as = module.params['remote_as']

        conf_str = CE_CREATE_BGP_PEER_HEADER % (
            vrf_name, peer_addr) + "<remoteAs>%s</remoteAs>" % remote_as + CE_CREATE_BGP_PEER_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Create bgp peer failed.')

        cmds = []
        cmd = "peer %s as-number %s" % (peer_addr, remote_as)
        cmds.append(cmd)

        return cmds

    def delete_bgp_peer(self, **kwargs):
        """ delete_bgp_peer """

        module = kwargs["module"]
        vrf_name = module.params['vrf_name']
        peer_addr = module.params['peer_addr']

        conf_str = CE_DELETE_BGP_PEER_HEADER % (
            vrf_name, peer_addr) + CE_DELETE_BGP_PEER_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Delete bgp peer failed.')

        cmds = []
        cmd = "undo peer %s" % peer_addr
        cmds.append(cmd)

        return cmds

    def merge_bgp_peer_other(self, **kwargs):
        """ merge_bgp_peer """

        module = kwargs["module"]
        vrf_name = module.params['vrf_name']
        peer_addr = module.params['peer_addr']

        conf_str = CE_MERGE_BGP_PEER_HEADER % (vrf_name, peer_addr)

        cmds = []

        description = module.params['description']
        if description:
            conf_str += "<description>%s</description>" % description

            cmd = "peer %s description %s" % (peer_addr, description)
            cmds.append(cmd)

        fake_as = module.params['fake_as']
        if fake_as:
            conf_str += "<fakeAs>%s</fakeAs>" % fake_as

            cmd = "peer %s local-as %s" % (peer_addr, fake_as)
            cmds.append(cmd)

        dual_as = module.params['dual_as']
        if dual_as != 'no_use':
            conf_str += "<dualAs>%s</dualAs>" % dual_as

            if dual_as == "true":
                cmd = "peer %s local-as %s dual-as" % (peer_addr, fake_as)
            else:
                cmd = "peer %s local-as %s" % (peer_addr, fake_as)
            cmds.append(cmd)

        conventional = module.params['conventional']
        if conventional != 'no_use':
            conf_str += "<conventional>%s</conventional>" % conventional

            if conventional == "true":
                cmd = "peer %s capability-advertise conventional" % peer_addr
            else:
                cmd = "undo peer %s capability-advertise conventional" % peer_addr
            cmds.append(cmd)

        route_refresh = module.params['route_refresh']
        if route_refresh != 'no_use':
            conf_str += "<routeRefresh>%s</routeRefresh>" % route_refresh

            if route_refresh == "true":
                cmd = "peer %s capability-advertise route-refresh" % peer_addr
            else:
                cmd = "undo peer %s capability-advertise route-refresh" % peer_addr
            cmds.append(cmd)

        four_byte_as = module.params['four_byte_as']
        if four_byte_as != 'no_use':
            conf_str += "<fourByteAs>%s</fourByteAs>" % four_byte_as

            if four_byte_as == "true":
                cmd = "peer %s capability-advertise 4-byte-as" % peer_addr
            else:
                cmd = "undo peer %s capability-advertise 4-byte-as" % peer_addr
            cmds.append(cmd)

        is_ignore = module.params['is_ignore']
        if is_ignore != 'no_use':
            conf_str += "<isIgnore>%s</isIgnore>" % is_ignore

            if is_ignore == "true":
                cmd = "peer %s ignore" % peer_addr
            else:
                cmd = "undo peer %s ignore" % peer_addr
            cmds.append(cmd)

        local_if_name = module.params['local_if_name']
        if local_if_name:
            conf_str += "<localIfName>%s</localIfName>" % local_if_name

            cmd = "peer %s connect-interface local_if_name" % peer_addr
            cmds.append(cmd)

        ebgp_max_hop = module.params['ebgp_max_hop']
        if ebgp_max_hop:
            conf_str += "<ebgpMaxHop>%s</ebgpMaxHop>" % ebgp_max_hop

            cmd = "peer %s ebgp-max-hop %s" % (peer_addr, ebgp_max_hop)
            cmds.append(cmd)

        valid_ttl_hops = module.params['valid_ttl_hops']
        if valid_ttl_hops:
            conf_str += "<validTtlHops>%s</validTtlHops>" % valid_ttl_hops

            cmd = "peer %s valid-ttl-hops %s" % (peer_addr, valid_ttl_hops)
            cmds.append(cmd)

        connect_mode = module.params['connect_mode']
        if connect_mode:
            conf_str += "<connectMode>%s</connectMode>" % connect_mode

            if connect_mode == "listenOnly":
                cmd = "peer %s listen-only" % peer_addr
                cmds.append(cmd)
            elif connect_mode == "connectOnly":
                cmd = "peer %s connect-only" % peer_addr
                cmds.append(cmd)
            elif connect_mode == "null":
                cmd = "peer %s listen-only" % peer_addr
                cmds.append(cmd)
                cmd = "peer %s connect-only" % peer_addr
                cmds.append(cmd)

        is_log_change = module.params['is_log_change']
        if is_log_change != 'no_use':
            conf_str += "<isLogChange>%s</isLogChange>" % is_log_change

            if is_log_change == "true":
                cmd = "peer %s log-change" % peer_addr
            else:
                cmd = "undo peer %s log-change" % peer_addr
            cmds.append(cmd)

        pswd_type = module.params['pswd_type']
        if pswd_type:
            conf_str += "<pswdType>%s</pswdType>" % pswd_type

        pswd_cipher_text = module.params['pswd_cipher_text']
        if pswd_cipher_text:
            conf_str += "<pswdCipherText>%s</pswdCipherText>" % pswd_cipher_text

            if pswd_type == "cipher":
                cmd = "peer %s password cipher %s" % (
                    peer_addr, pswd_cipher_text)
            elif pswd_type == "simple":
                cmd = "peer %s password simple %s" % (
                    peer_addr, pswd_cipher_text)
            cmds.append(cmd)

        keep_alive_time = module.params['keep_alive_time']
        if keep_alive_time:
            conf_str += "<keepAliveTime>%s</keepAliveTime>" % keep_alive_time

            cmd = "peer %s timer keepalive %s" % (peer_addr, keep_alive_time)
            cmds.append(cmd)

        hold_time = module.params['hold_time']
        if hold_time:
            conf_str += "<holdTime>%s</holdTime>" % hold_time

            cmd = "peer %s timer hold %s" % (peer_addr, hold_time)
            cmds.append(cmd)

        min_hold_time = module.params['min_hold_time']
        if min_hold_time:
            conf_str += "<minHoldTime>%s</minHoldTime>" % min_hold_time

            cmd = "peer %s timer min-holdtime %s" % (peer_addr, min_hold_time)
            cmds.append(cmd)

        key_chain_name = module.params['key_chain_name']
        if key_chain_name:
            conf_str += "<keyChainName>%s</keyChainName>" % key_chain_name

            cmd = "peer %s keychain %s" % (peer_addr, key_chain_name)
            cmds.append(cmd)

        conn_retry_time = module.params['conn_retry_time']
        if conn_retry_time:
            conf_str += "<connRetryTime>%s</connRetryTime>" % conn_retry_time

            cmd = "peer %s timer connect-retry %s" % (
                peer_addr, conn_retry_time)
            cmds.append(cmd)

        tcp_mss = module.params['tcp_MSS']
        if tcp_mss:
            conf_str += "<tcpMSS>%s</tcpMSS>" % tcp_mss

            cmd = "peer %s tcp-mss %s" % (peer_addr, tcp_mss)
            cmds.append(cmd)

        mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
        if mpls_local_ifnet_disable != 'no_use':
            conf_str += "<mplsLocalIfnetDisable>%s</mplsLocalIfnetDisable>" % mpls_local_ifnet_disable

        prepend_global_as = module.params['prepend_global_as']
        if prepend_global_as != 'no_use':
            conf_str += "<prependGlobalAs>%s</prependGlobalAs>" % prepend_global_as

            if prepend_global_as == "true":
                cmd = "peer %s public-as-only" % peer_addr
            else:
                cmd = "undo peer %s public-as-only" % peer_addr
            cmds.append(cmd)

        prepend_fake_as = module.params['prepend_fake_as']
        if prepend_fake_as != 'no_use':
            conf_str += "<prependFakeAs>%s</prependFakeAs>" % prepend_fake_as

        conf_str += CE_MERGE_BGP_PEER_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Merge bgp peer other failed.')

        return cmds

    def merge_peer_bfd(self, **kwargs):
        """ merge_peer_bfd """

        module = kwargs["module"]
        vrf_name = module.params['vrf_name']
        peer_addr = module.params['peer_addr']

        conf_str = CE_MERGE_PEER_BFD_HEADER % (vrf_name, peer_addr)

        cmds = []

        is_bfd_block = module.params['is_bfd_block']
        if is_bfd_block != 'no_use':
            conf_str += "<isBfdBlock>%s</isBfdBlock>" % is_bfd_block

            if is_bfd_block == "true":
                cmd = "peer %s bfd block" % peer_addr
            else:
                cmd = "undo peer %s bfd block" % peer_addr
            cmds.append(cmd)

        multiplier = module.params['multiplier']
        if multiplier:
            conf_str += "<multiplier>%s</multiplier>" % multiplier

            cmd = "peer %s bfd detect-multiplier %s" % (peer_addr, multiplier)
            cmds.append(cmd)

        is_bfd_enable = module.params['is_bfd_enable']
        if is_bfd_enable != 'no_use':
            conf_str += "<isBfdEnable>%s</isBfdEnable>" % is_bfd_enable

            if is_bfd_enable == "true":
                cmd = "peer %s bfd enable" % peer_addr
            else:
                cmd = "undo peer %s bfd enable" % peer_addr
            cmds.append(cmd)

        rx_interval = module.params['rx_interval']
        if rx_interval:
            conf_str += "<rxInterval>%s</rxInterval>" % rx_interval

            cmd = "peer %s bfd min-rx-interval %s" % (peer_addr, rx_interval)
            cmds.append(cmd)

        tx_interval = module.params['tx_interval']
        if tx_interval:
            conf_str += "<txInterval>%s</txInterval>" % tx_interval

            cmd = "peer %s bfd min-tx-interval %s" % (peer_addr, tx_interval)
            cmds.append(cmd)

        is_single_hop = module.params['is_single_hop']
        if is_single_hop != 'no_use':
            conf_str += "<isSingleHop>%s</isSingleHop>" % is_single_hop

            if is_single_hop == "true":
                cmd = "peer %s bfd enable single-hop-prefer" % peer_addr
            else:
                cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
            cmds.append(cmd)

        conf_str += CE_MERGE_PEER_BFD_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Merge peer bfd failed.')

        return cmds

    def delete_peer_bfd(self, **kwargs):
        """ delete_peer_bfd """

        module = kwargs["module"]
        vrf_name = module.params['vrf_name']
        peer_addr = module.params['peer_addr']

        conf_str = CE_DELETE_PEER_BFD_HEADER % (vrf_name, peer_addr)

        cmds = []

        is_bfd_block = module.params['is_bfd_block']
        if is_bfd_block != 'no_use':
            conf_str += "<isBfdBlock>%s</isBfdBlock>" % is_bfd_block

            cmd = "undo peer %s bfd block" % peer_addr
            cmds.append(cmd)

        multiplier = module.params['multiplier']
        if multiplier:
            conf_str += "<multiplier>%s</multiplier>" % multiplier

            cmd = "undo peer %s bfd detect-multiplier %s" % (
                peer_addr, multiplier)
            cmds.append(cmd)

        is_bfd_enable = module.params['is_bfd_enable']
        if is_bfd_enable != 'no_use':
            conf_str += "<isBfdEnable>%s</isBfdEnable>" % is_bfd_enable

            cmd = "undo peer %s bfd enable" % peer_addr
            cmds.append(cmd)

        rx_interval = module.params['rx_interval']
        if rx_interval:
            conf_str += "<rxInterval>%s</rxInterval>" % rx_interval

            cmd = "undo peer %s bfd min-rx-interval %s" % (
                peer_addr, rx_interval)
            cmds.append(cmd)

        tx_interval = module.params['tx_interval']
        if tx_interval:
            conf_str += "<txInterval>%s</txInterval>" % tx_interval

            cmd = "undo peer %s bfd min-tx-interval %s" % (
                peer_addr, tx_interval)
            cmds.append(cmd)

        is_single_hop = module.params['is_single_hop']
        if is_single_hop != 'no_use':
            conf_str += "<isSingleHop>%s</isSingleHop>" % is_single_hop

            cmd = "undo peer %s bfd enable single-hop-prefer" % peer_addr
            cmds.append(cmd)

        conf_str += CE_DELETE_PEER_BFD_TAIL

        recv_xml = self.netconf_set_config(module=module, conf_str=conf_str)

        if "<ok/>" not in recv_xml:
            module.fail_json(msg='Error: Delete peer bfd failed.')

        return cmds

def main():
    """ main """

    argument_spec = dict(
        state=dict(choices=['present', 'absent'], default='present'),
        vrf_name=dict(type='str', required=True),
        peer_addr=dict(type='str', required=True),
        remote_as=dict(type='str', required=True),
        description=dict(type='str'),
        fake_as=dict(type='str'),
        dual_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        conventional=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        route_refresh=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        four_byte_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        is_ignore=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        local_if_name=dict(type='str'),
        ebgp_max_hop=dict(type='str'),
        valid_ttl_hops=dict(type='str'),
        connect_mode=dict(choices=['listenOnly', 'connectOnly', 'null']),
        is_log_change=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        pswd_type=dict(choices=['null', 'cipher', 'simple']),
        pswd_cipher_text=dict(type='str', no_log=True),
        keep_alive_time=dict(type='str'),
        hold_time=dict(type='str'),
        min_hold_time=dict(type='str'),
        key_chain_name=dict(type='str'),
        conn_retry_time=dict(type='str'),
        tcp_MSS=dict(type='str'),
        mpls_local_ifnet_disable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        prepend_global_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        prepend_fake_as=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        is_bfd_block=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        multiplier=dict(type='str'),
        is_bfd_enable=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']),
        rx_interval=dict(type='str'),
        tx_interval=dict(type='str'),
        is_single_hop=dict(type='str', default='no_use', choices=['no_use', 'true', 'false']))

    argument_spec.update(ce_argument_spec)
    module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)

    changed = False
    proposed = dict()
    existing = dict()
    end_state = dict()
    updates = []

    state = module.params['state']
    vrf_name = module.params['vrf_name']
    peer_addr = module.params['peer_addr']
    remote_as = module.params['remote_as']
    description = module.params['description']
    fake_as = module.params['fake_as']
    dual_as = module.params['dual_as']
    conventional = module.params['conventional']
    route_refresh = module.params['route_refresh']
    four_byte_as = module.params['four_byte_as']
    is_ignore = module.params['is_ignore']
    local_if_name = module.params['local_if_name']
    ebgp_max_hop = module.params['ebgp_max_hop']
    valid_ttl_hops = module.params['valid_ttl_hops']
    connect_mode = module.params['connect_mode']
    is_log_change = module.params['is_log_change']
    pswd_type = module.params['pswd_type']
    pswd_cipher_text = module.params['pswd_cipher_text']
    keep_alive_time = module.params['keep_alive_time']
    hold_time = module.params['hold_time']
    min_hold_time = module.params['min_hold_time']
    key_chain_name = module.params['key_chain_name']
    conn_retry_time = module.params['conn_retry_time']
    tcp_mss = module.params['tcp_MSS']
    mpls_local_ifnet_disable = module.params['mpls_local_ifnet_disable']
    prepend_global_as = module.params['prepend_global_as']
    prepend_fake_as = module.params['prepend_fake_as']
    is_bfd_block = module.params['is_bfd_block']
    multiplier = module.params['multiplier']
    is_bfd_enable = module.params['is_bfd_enable']
    rx_interval = module.params['rx_interval']
    tx_interval = module.params['tx_interval']
    is_single_hop = module.params['is_single_hop']

    ce_bgp_peer_obj = BgpNeighbor()

    # get proposed
    proposed["state"] = state
    if vrf_name:
        proposed["vrf_name"] = vrf_name
    if peer_addr:
        proposed["peer_addr"] = peer_addr
    if remote_as:
        proposed["remote_as"] = remote_as
    if description:
        proposed["description"] = description
    if fake_as:
        proposed["fake_as"] = fake_as
    if dual_as != 'no_use':
        proposed["dual_as"] = dual_as
    if conventional != 'no_use':
        proposed["conventional"] = conventional
    if route_refresh != 'no_use':
        proposed["route_refresh"] = route_refresh
    if four_byte_as != 'no_use':
        proposed["four_byte_as"] = four_byte_as
    if is_ignore != 'no_use':
        proposed["is_ignore"] = is_ignore
    if local_if_name:
        proposed["local_if_name"] = local_if_name
    if ebgp_max_hop:
        proposed["ebgp_max_hop"] = ebgp_max_hop
    if valid_ttl_hops:
        proposed["valid_ttl_hops"] = valid_ttl_hops
    if connect_mode:
        proposed["connect_mode"] = connect_mode
    if is_log_change != 'no_use':
        proposed["is_log_change"] = is_log_change
    if pswd_type:
        proposed["pswd_type"] = pswd_type
    if pswd_cipher_text:
        proposed["pswd_cipher_text"] = pswd_cipher_text
    if keep_alive_time:
        proposed["keep_alive_time"] = keep_alive_time
    if hold_time:
        proposed["hold_time"] = hold_time
    if min_hold_time:
        proposed["min_hold_time"] = min_hold_time
    if key_chain_name:
        proposed["key_chain_name"] = key_chain_name
    if conn_retry_time:
        proposed["conn_retry_time"] = conn_retry_time
    if tcp_mss:
        proposed["tcp_MSS"] = tcp_mss
    if mpls_local_ifnet_disable != 'no_use':
        proposed["mpls_local_ifnet_disable"] = mpls_local_ifnet_disable
    if prepend_global_as != 'no_use':
        proposed["prepend_global_as"] = prepend_global_as
    if prepend_fake_as != 'no_use':
        proposed["prepend_fake_as"] = prepend_fake_as
    if is_bfd_block != 'no_use':
        proposed["is_bfd_block"] = is_bfd_block
    if multiplier:
        proposed["multiplier"] = multiplier
    if is_bfd_enable != 'no_use':
        proposed["is_bfd_enable"] = is_bfd_enable
    if rx_interval:
        proposed["rx_interval"] = rx_interval
    if tx_interval:
        proposed["tx_interval"] = tx_interval
    if is_single_hop != 'no_use':
        proposed["is_single_hop"] = is_single_hop

    if not ce_bgp_peer_obj:
        module.fail_json(msg='Error: Init module failed.')

    need_bgp_peer_enable = ce_bgp_peer_obj.check_bgp_peer_args(module=module)
    need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
        module=module)
    need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
        module=module)
    need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
        module=module)

    # bgp peer config
    if need_bgp_peer_enable["need_cfg"]:

        if state == "present":

            if remote_as:

                bgp_peer_exist = ce_bgp_peer_obj.get_bgp_peer(module=module)
                existing["bgp peer"] = bgp_peer_exist

                bgp_peer_new = (peer_addr, remote_as)

                if len(bgp_peer_exist) == 0:
                    cmd = ce_bgp_peer_obj.create_bgp_peer(module=module)
                    changed = True
                    for item in cmd:
                        updates.append(item)

                elif bgp_peer_new in bgp_peer_exist:
                    pass

                else:
                    cmd = ce_bgp_peer_obj.merge_bgp_peer(module=module)
                    changed = True
                    for item in cmd:
                        updates.append(item)

                bgp_peer_end = ce_bgp_peer_obj.get_bgp_peer(module=module)
                end_state["bgp peer"] = bgp_peer_end

        else:

            bgp_peer_exist = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
            existing["bgp peer"] = bgp_peer_exist

            bgp_peer_new = (peer_addr)

            if len(bgp_peer_exist) == 0:
                pass

            elif bgp_peer_new in bgp_peer_exist:
                cmd = ce_bgp_peer_obj.delete_bgp_peer(module=module)
                changed = True
                for item in cmd:
                    updates.append(item)

            bgp_peer_end = ce_bgp_peer_obj.get_bgp_del_peer(module=module)
            end_state["bgp peer"] = bgp_peer_end

    # bgp peer other args
    exist_tmp = dict()
    for item in need_bgp_peer_other_rst:
        if item != "need_cfg":
            exist_tmp[item] = need_bgp_peer_other_rst[item]
    if exist_tmp:
        existing["bgp peer other"] = exist_tmp

    if need_bgp_peer_other_rst["need_cfg"]:

        if state == "present":
            cmd = ce_bgp_peer_obj.merge_bgp_peer_other(module=module)
            changed = True
            for item in cmd:
                updates.append(item)

    need_bgp_peer_other_rst = ce_bgp_peer_obj.check_bgp_peer_other_args(
        module=module)
    end_tmp = dict()
    for item in need_bgp_peer_other_rst:
        if item != "need_cfg":
            end_tmp[item] = need_bgp_peer_other_rst[item]
    if end_tmp:
        end_state["bgp peer other"] = end_tmp

    # peer bfd args
    if state == "present":
        exist_tmp = dict()
        for item in need_peer_bfd_merge_rst:
            if item != "need_cfg":
                exist_tmp[item] = need_peer_bfd_merge_rst[item]
        if exist_tmp:
            existing["peer bfd"] = exist_tmp

        if need_peer_bfd_merge_rst["need_cfg"]:
            cmd = ce_bgp_peer_obj.merge_peer_bfd(module=module)
            changed = True
            for item in cmd:
                updates.append(item)

        need_peer_bfd_merge_rst = ce_bgp_peer_obj.check_peer_bfd_merge_args(
            module=module)
        end_tmp = dict()
        for item in need_peer_bfd_merge_rst:
            if item != "need_cfg":
                end_tmp[item] = need_peer_bfd_merge_rst[item]
        if end_tmp:
            end_state["peer bfd"] = end_tmp
    else:
        exist_tmp = dict()
        for item in need_peer_bfd_del_rst:
            if item != "need_cfg":
                exist_tmp[item] = need_peer_bfd_del_rst[item]
        if exist_tmp:
            existing["peer bfd"] = exist_tmp

        # has already delete with bgp peer

        need_peer_bfd_del_rst = ce_bgp_peer_obj.check_peer_bfd_delete_args(
            module=module)
        end_tmp = dict()
        for item in need_peer_bfd_del_rst:
            if item != "need_cfg":
                end_tmp[item] = need_peer_bfd_del_rst[item]
        if end_tmp:
            end_state["peer bfd"] = end_tmp

    results = dict()
    results['proposed'] = proposed
    results['existing'] = existing
    results['changed'] = changed
    results['end_state'] = end_state
    results['updates'] = updates

    module.exit_json(**results)

if __name__ == '__main__':
    main()


text:
package io.bootique.cayenne.v42;

import io.bootique.di.BQModule;
import io.bootique.junit5.BQTest;
import io.bootique.junit5.BQTestFactory;
import io.bootique.junit5.BQTestTool;
import org.apache.cayenne.CayenneDataObject;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.annotation.PostPersist;
import org.apache.cayenne.configuration.server.ServerRuntime;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

@BQTest
public class CayenneModule_ListenersIT {

    @BQTestTool
    final BQTestFactory testFactory = new BQTestFactory();

    private ServerRuntime runtimeWithListeners(Object... listeners) {

        BQModule listenersModule = (binder) -> {
            CayenneModuleExtender extender = CayenneModule.extend(binder);
            Arrays.asList(listeners).forEach(extender::addListener);
        };

        return testFactory.app("--config=classpath:genericconfig.yml")
                .autoLoadModules()
                .module(listenersModule)
                .createRuntime()
                .getInstance(ServerRuntime.class);
    }

    @Test
    public void testListeners() {

        L1 l1 = new L1();

        CayenneDataObject o1 = new CayenneDataObject();
        o1.setObjectId(ObjectId.of("T1"));
        o1.writeProperty("name", "n" + 1);

        CayenneDataObject o2 = new CayenneDataObject();
        o2.setObjectId(ObjectId.of("T1"));
        o2.writeProperty("name", "n" + 2);

        ServerRuntime runtime = runtimeWithListeners(l1);
        try {
            ObjectContext c = runtime.newContext();
            c.registerNewObject(o1);
            c.registerNewObject(o2);
            c.commitChanges();

        } finally {
            runtime.shutdown();
        }

        assertEquals(2, l1.postPersisted.size());
        assertTrue(l1.postPersisted.contains(o1));
        assertTrue(l1.postPersisted.contains(o2));
    }

    static class L1 {

        List<Object> postPersisted = new ArrayList<>();

        @PostPersist
        public void postPersist(Object o) {
            postPersisted.add(o);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
import rospy
from std_msgs.msg import String
from std_msgs.msg import Int64
from info_task.msg import EmptyAction, Clicks
from info_task.utils import Gaze, Head, PTU
from strands_executive_msgs.abstract_task_server import AbstractTaskServer
import strands_webserver.client_utils

class InfoTaskServer(AbstractTaskServer):
    def __init__(self, name, url_suffix=None):
        rospy.loginfo("Starting InfoTaskServer: %s" % name)
        # Creating action clients
        #self.gaze = Gaze()
        #self.head = Head()
        #self.ptu = PTU()

        self.url_suffix = url_suffix

        self.url_suffix = url_suffix

        self.url_suffix = url_suffix

        # interaction storage
        self.interaction_times = []
        self.pages = []

        self.extension_time = rospy.get_param("~extension_time", 30.0)
        self.reset_time = 0.0

        # Creating activity subscriber and publisher
        self.pub = rospy.Publisher("/info_terminal/task_outcome", Clicks, queue_size=10, latch=True)

        rospy.loginfo(" ... starting " + name)
        super(InfoTaskServer, self).__init__(
            name=name,
            action_type=EmptyAction,
            interruptible=True
        )
        rospy.Subscriber("/info_terminal/active_screen", String, self.button_pressed_callback)
        rospy.Subscriber("/info_terminal/cancel_info_task", Int64 , self.cancel_info_task_callback)
        rospy.loginfo(" ... started " + name)

    def execute(self, goal):
        self.ptu.turnPTU(-180, 10) # Looking back and slightly down
        self.head.turnHead()       # Turning head backwards
        self.gaze.people()         # Looking at upper bodies

        # Showing info terminal webserver
        if self.url_suffix is not None:
            strands_webserver.client_utils.display_url(0,
                'http://localhost:8080/?page=' + self.url_suffix)
        else:
            strands_webserver.client_utils.display_url(0,
                'http://localhost:8080/')

        rate = rospy.Rate(1)
        # preempt will not be requested while activity is happening
        while not rospy.is_shutdown() and not self.server.is_preempt_requested():
            # loop for duration
            if self.reset_time < rospy.Time.now().to_sec():
                self.interruptible = True
            rospy.logdebug("Info task active with interruptable: %s" % str(self.interruptible))
            rate.sleep()

        # Reset ptu, head and gaze
        self.ptu.turnPTU(0, 0)
        self.gaze.preempt()
        self.head.resetHead()

        if not self.server.is_preempt_requested():
            self.server.set_succeeded()
        else:
            self.server.set_preempted()

    def create(self, req):
        task = super(InfoTaskServer, self).create(req)
        if task.max_duration.secs == 0:
            task.max_duration = task.end_before - task.start_after # Default execution time: window length
        if task.priority == 0:
            task.priority = 1
        return task

    def button_pressed_callback(self, active_screen):
        # reset timeout
        if self.server.is_active():
            rospy.loginfo('button_pressed_callback')
            self.interaction_times.append(rospy.Time.now())
            self.pages.append(active_screen.data)
            self.reset_time = rospy.Time.now().to_sec() + self.extension_time
            self.interruptible = False

    def cancel_info_task_callback(self, msg):
        if msg.data >= 0:
            self.preempt_cb()

    def preempt_cb(self):
        clicks = Clicks()
        clicks.time_array = self.interaction_times
        clicks.page_array = self.pages

        self.interaction_times = []
        self.pages = []

        self.pub.publish(clicks)

if __name__ == "__main__":
    rospy.init_node("info_task_server")
    urls = ['news',
            'menu', 'menures',
            'info', 'weather', 'photos']
    servers = {}
    for u in urls:
        servers[u] = InfoTaskServer(
            '%s/%s' % (rospy.get_name(), u)
            )
    servers['default'] = InfoTaskServer(
        rospy.get_name()
        )

    rospy.spin()


text:
package org.gradle.nativebinaries.language.cpp.internal;

import org.gradle.nativebinaries.language.internal.AbstractNativeCompileSpec;

public class DefaultCppCompileSpec extends AbstractNativeCompileSpec implements CppCompileSpec {
}


text:
interface IQrCodeTerminalService {
	generate(url: string): void;
}


text:
use Search::Kino03::KinoSearch;

1;

__END__

__XS__

MODULE = Search::Kino03::KinoSearch   PACKAGE = Search::Kino03::KinoSearch::Util::StringHelper

=for comment

Turn an SV's UTF8 flag on.  Equivalent to Encode::_utf8_on, but we don't have
to load Encode.

=cut

void
utf8_flag_on(sv)
    SV *sv;
PPCODE:
    SvUTF8_on(sv);

=for comment

Turn an SV's UTF8 flag off.

=cut

void
utf8_flag_off(sv)
    SV *sv;
PPCODE:
    SvUTF8_off(sv);

SV*
to_base36(num)
    chy_u32_t num;
CODE:
{
    kino_CharBuf *buf = kino_StrHelp_to_base36(num);
    RETVAL = XSBind_cb_to_sv(buf);
    KINO_DECREF(buf);
}
OUTPUT: RETVAL

IV
from_base36(str)
    char *str;
CODE:
    RETVAL = strtol(str, NULL, 36);
OUTPUT: RETVAL

=for comment

Upgrade a SV to UTF8, converting Latin1 if necessary. Equivalent to utf::upgrade().

=cut

void
utf8ify(sv)
    SV *sv;
PPCODE:
    sv_utf8_upgrade(sv);

chy_bool_t
utf8_valid(sv)
    SV *sv;
CODE:
{
    STRLEN len;
    char *ptr = SvPV(sv, len);
    RETVAL = kino_StrHelp_utf8_valid(ptr, len);
}
OUTPUT: RETVAL

=for comment

Concatenate one scalar onto the end of the other, ignoring UTF-8 status of the
second scalar.  This is necessary because $not_utf8 . $utf8 results in a
scalar which has been infected by the UTF-8 flag of the second argument.

=cut

void
cat_bytes(sv, catted)
    SV *sv;
    SV *catted;
PPCODE:
{
    STRLEN len;
    char *ptr = SvPV(catted, len);
    if (SvUTF8(sv)) { KINO_THROW("Can't cat_bytes onto a UTF-8 SV"); }
    sv_catpvn(sv, ptr, len);
}

__COPYRIGHT__

Copyright 2005-2009 Marvin Humphrey

This program is free software; you can redistribute it and/or modify
under the same terms as Perl itself.


text:
<?php
class Major extends Eloquent {
	protected $table = 'majors';
	public function category() {
        return $this->belongsTo('Category');
    }
}


text:
"use strict";

// returns the index of the lowest item in the list
const getFirstIndex = times => {

    let low = 0;
    for (let i = 1; i < times.length; i++) {
        if (times[i] < times[low])
            low = i;
    }

    return low;
};

module.exports = getFirstIndex;


text:
import * as React from 'react';
import { IconBaseProps } from 'react-icon-base';
export default class FaStrikethrough extends React.Component<IconBaseProps, any> { }


text:
/* DIGIT.H - header file for DIGIT.C
 */

/* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
   Security, Inc. All rights reserved.
 */

void NN_DigitMult PROTO_LIST ((NN_DIGIT [2], NN_DIGIT, NN_DIGIT));
void NN_DigitDiv PROTO_LIST ((NN_DIGIT *, NN_DIGIT [2], NN_DIGIT));


text:
Checks Ghost themes for errors, deprecations, best practices and looks to see which features are supported.
Aims to generate a compatibility report and feature listing for themes.

To install:

`npm install gscan`

## CLI usage

To run a local directory through the checks:

`gscan /path/to/theme/directory`

To run a local zip file through the checks:

`gscan /path/to/theme.zip -z`

## Lib usage

```js
var gscan = require('gscan');

gscan.checkZip({
    path: 'path-to-zip',
    name: 'my-theme'
}).then(function (result) {
    console.log(result);
}).catch(function(err) {
    console.log(err);
});
```

## Web usage

You can run a web interface for uploading a zip file:

`node app/index.js` or `nodemon` or `npm start` or `MODE=long npm start`

Then navigate to `http://localhost:2369`, and use the form to upload your file

## Result types:

- Errors: these are issues which will cause your theme to not work properly. These must be fixed.
- Warnings: these are usually related to deprecated features. These should be fixed.
- Recommendations: these are advisories about best practice. Fixing these will improve your theme.
- Features: detected features which may impact on compatibility. Nothing to do :)

## Still To Do:

- Support for running the checks against a GitHub repository
- Many, many more checks
- Detailed advice for each check/result
- Compatibility report
- Feature listing


text:
module Similarweb
  module Traffic
    module BounceRate

      # NOTE: start_date, end_date format: YYYY-MM

      def desktop_bounce_rate(domain, start_date, end_date, granularity = 'daily')
        response = self.http_client.get "v1/website/#{domain}/traffic-and-engagement/bounce-rate?api_key=#{self.api_key}&start_date=#{start_date}&end_date=#{end_date}&main_domain_only=false&granularity=#{granularity}"
        JSON.parse(response.body)
      end

      def mobile_bounce_rate(domain, start_date, end_date, granularity = 'daily')
        response = self.http_client.get "v2/website/#{domain}/mobile-web/bounce-rate?api_key=#{self.api_key}&start_date=#{start_date}&end_date=#{end_date}&granularity=#{frequency}"
        JSON.parse(response.body)
      end

    end
  end
end


text:
.. _integrate-assignment-backend-ldap:

=======================================
Integrate assignment back end with LDAP
=======================================

When you configure the OpenStack Identity service to use LDAP servers,
you can split authentication and authorization using the *assignment*
feature. Integrating the *assignment* back end with LDAP allows
administrators to use projects (tenant), roles, domains, and role
assignments in LDAP.

.. note::

   Be aware of domain-specific back end limitations when configuring
   OpenStack Identity. The OpenStack Identity service
   does not support domain-specific assignment back ends.
   Using LDAP as an assignment back end is not
   recommended.

.. important::

   For OpenStack Identity assignments to access LDAP servers, you must
   define the destination LDAP server in the ``keystone.conf`` file.
   For more information, see :ref:`integrate-identity-with-ldap`.

**To integrate assignment back ends with LDAP**

#. Enable the assignment driver. In the ``[assignment]`` section, set the
   ``driver`` configuration key to
   ``keystone.assignment.backends.sql.Assignment``:

   .. code-block:: ini

      [assignment]
      #driver = keystone.assignment.backends.sql.Assignment
      driver = keystone.assignment.backends.ldap.Assignment

#. Create the organizational units (OU) in the LDAP directory, and define
   their corresponding location in the ``keystone.conf`` file:

   .. code-block:: ini

      [ldap]
      role_tree_dn =
      role_objectclass = inetOrgPerson

      project_tree_dn = ou=Groups,dc=example,dc=org
      project_objectclass = groupOfNames

   .. note::

      These schema attributes are extensible for compatibility with
      various schemas. For example, this entry maps to the groupOfNames
      attribute in Active Directory:

      .. code-block:: ini

         project_objectclass = groupOfNames

#. A read-only implementation is recommended for LDAP integration. These
   permissions are applied to object types in the ``keystone.conf`` file:

   .. code-block:: ini

      [ldap]
      role_allow_create = False
      role_allow_update = False
      role_allow_delete = False

      project_allow_create = False
      project_allow_update = False
      project_allow_delete = False

#. Restart the OpenStack Identity service.

   .. warning::

      During service restart, authentication and authorization are
      unavailable.

**Additional LDAP integration settings.**

Set these options in the ``/etc/keystone/keystone.conf`` file for a
single LDAP server, or ``/etc/keystone/domains/keystone.DOMAIN_NAME.conf``
files for multiple back ends.

Filters
  Use filters to control the scope of data presented through LDAP.

  .. code-block:: ini

     [ldap]
     project_filter = (member=cn=openstack-user,ou=workgroups,
     dc=example,dc=org)
     role_filter =

  .. warning::

     Filtering method

Assignment attribute mapping
  Mask account status values (include any additional attribute
  mappings) for compatibility with various directory services.
  Superfluous accounts are filtered with user\_filter.

  Setting attribute ignore to list of attributes stripped off on
  update.

  .. code-block:: ini

     [ldap]
     role_id_attribute = cn
     role_name_attribute = ou
     role_member_attribute = roleOccupant
     role_additional_attribute_mapping =
     role_attribute_ignore =

     project_id_attribute = cn
     project_name_attribute = ou
     project_member_attribute = member
     project_desc_attribute = description
     project_enabled_attribute = enabled
     project_domain_id_attribute = businessCategory
     project_additional_attribute_mapping =
     project_attribute_ignore =

Enabled emulation
  An alternative method to determine if a project is enabled or not is
  to check if that project is a member of the emulation group.

  Use DN of the group entry to hold enabled projects when using
  enabled emulation.

  .. code-block:: ini

     [ldap]
     project_enabled_emulation = false
     project_enabled_emulation_dn = false