apache-ignite

Форк
0
211 строк · 6.4 Кб
1
# Licensed to the Apache Software Foundation (ASF) under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#    http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15

16
"""
17
This module contains JMX Console client and different utilities and mixins to retrieve ignite node parameters
18
and attributes.
19
"""
20
import os
21
import re
22

23
from ignitetest.services.utils.decorators import memoize
24
from ignitetest.services.utils.jvm_utils import java_version, java_major_version
25

26

27
def ignite_jmx_mixin(node, service):
28
    """
29
    Dynamically mixin JMX attributes to Ignite service node.
30
    :param node: Ignite service node.
31
    :param service: Ignite service.
32
    """
33
    setattr(node, 'pids', service.pids(node, service.main_java_class))
34
    setattr(node, 'install_root', service.install_root)
35
    base_cls = node.__class__
36
    base_cls_name = node.__class__.__name__
37
    node.__class__ = type(base_cls_name, (base_cls, IgniteJmxMixin), {})
38

39

40
class JmxMBean:
41
    """
42
    Dynamically exposes JMX MBean attributes.
43
    """
44
    def __init__(self, client, name):
45
        self.client = client
46
        self.name = name
47

48
    def __getattr__(self, attr):
49
        """
50
        Retrieves through JMX client MBean attributes.
51
        :param attr: Attribute name.
52
        :return: Attribute value.
53
        """
54
        return self.client.mbean_attribute(self.name, attr)
55

56

57
class JmxClient:
58
    """JMX client, invokes jmxterm on node locally.
59
    """
60
    def __init__(self, node):
61
        self.node = node
62
        self.install_root = node.install_root
63
        self.pid = node.pids[0]
64
        self.java_major = java_major_version(java_version(self.node))
65

66
    @property
67
    def jmx_util_cmd(self):
68
        """
69
        :return: jmxterm prepared command line invocation.
70
        """
71
        extra_flag = "--add-exports jdk.jconsole/sun.tools.jconsole=ALL-UNNAMED" if self.java_major >= 15 else ""
72

73
        return os.path.join(f"java {extra_flag} -jar {self.install_root}/jmxterm.jar -v silent -n")
74

75
    @memoize
76
    def find_mbean(self, pattern, negative_pattern=None, domain='org.apache'):
77
        """
78
        Find mbean by specified pattern and domain on node.
79
        :param pattern: MBean name pattern.
80
        :param negative_pattern: if passed used to filter out some MBeans
81
        :param domain: Domain of MBean
82
        :return: JmxMBean instance
83
        """
84
        cmd = "echo $'open %s\\n beans -d %s \\n close' | %s | grep -E -o '%s'" \
85
              % (self.pid, domain, self.jmx_util_cmd, pattern)
86

87
        if negative_pattern:
88
            cmd += " | grep -E -v '%s'" % negative_pattern
89

90
        name = next(self.__run_cmd(cmd)).strip()
91

92
        return JmxMBean(self, name)
93

94
    def mbean_attribute(self, mbean, attr):
95
        """
96
        Get MBean attribute.
97
        :param mbean: MBean name
98
        :param attr: Attribute name
99
        :return: Attribute value
100
        """
101
        cmd = "echo $'open %s\\n get -b %s %s \\n close' | %s | sed 's/%s = \\(.*\\);/\\1/'" \
102
              % (self.pid, mbean, attr, self.jmx_util_cmd, attr)
103

104
        return iter(s.strip() for s in self.__run_cmd(cmd))
105

106
    def __run_cmd(self, cmd):
107
        return self.node.account.ssh_capture(cmd, allow_fail=False, callback=str, combine_stderr=False)
108

109

110
class DiscoveryInfo:
111
    """ Ignite service node discovery info, obtained from DiscoverySpi mbean.
112
    """
113
    def __init__(self, coordinator, local_raw):
114
        self._local_raw = local_raw
115
        self._coordinator = coordinator
116

117
    @property
118
    def node_id(self):
119
        """
120
        :return: Local node id.
121
        """
122
        return self.__find__("id=([^\\s]+),")
123

124
    @property
125
    def coordinator(self):
126
        """
127
        :return: Coordinator node id.
128
        """
129
        return self._coordinator
130

131
    @property
132
    def consistent_id(self):
133
        """
134
        :return: Node consistent id, if presents (only in TcpDiscovery).
135
        """
136
        return self.__find__("consistentId=([^\\s]+),")
137

138
    @property
139
    def is_client(self):
140
        """
141
        :return: True if node is client.
142
        """
143
        return self.__find__("isClient=([^\\s]+),") == "true"
144

145
    @property
146
    def order(self):
147
        """
148
        :return: Topology order.
149
        """
150
        val = self.__find__("order=(\\d+),")
151
        return int(val) if val else -1
152

153
    @property
154
    def int_order(self):
155
        """
156
        :return: Internal order (TcpDiscovery).
157
        """
158
        val = self.__find__("intOrder=(\\d+),")
159
        return int(val) if val else -1
160

161
    def __find__(self, pattern):
162
        res = re.search(pattern, self._local_raw)
163
        return res.group(1) if res else None
164

165

166
class IgniteJmxMixin:
167
    """
168
    Mixin to IgniteService node, exposing useful properties, obtained from JMX.
169
    """
170
    @memoize
171
    def jmx_client(self):
172
        """
173
        :return: JmxClient instance.
174
        """
175
        # noinspection PyTypeChecker
176
        return JmxClient(self)
177

178
    @memoize
179
    def node_id(self):
180
        """
181
        :return: Local node id.
182
        """
183
        return next(self.kernal_mbean().LocalNodeId).strip()
184

185
    def discovery_info(self):
186
        """
187
        :return: DiscoveryInfo instance.
188
        """
189
        disco_mbean = self.disco_mbean()
190
        crd = next(disco_mbean.Coordinator).strip()
191
        local = next(disco_mbean.LocalNodeFormatted).strip()
192

193
        return DiscoveryInfo(crd, local)
194

195
    def kernal_mbean(self):
196
        """
197
        :return: IgniteKernal MBean.
198
        """
199
        return self.jmx_client().find_mbean('.*group=Kernal.*name=IgniteKernal')
200

201
    @memoize
202
    def disco_mbean(self):
203
        """
204
        :return: DiscoverySpi MBean.
205
        """
206
        disco_spi = next(self.kernal_mbean().DiscoverySpiFormatted).strip()
207

208
        if 'ZookeeperDiscoverySpi' in disco_spi:
209
            return self.jmx_client().find_mbean('.*group=SPIs.*name=ZookeeperDiscoverySpi')
210

211
        return self.jmx_client().find_mbean('.*group=SPIs.*name=TcpDiscoverySpi')
212

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.