• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.52
/exist-core/src/main/java/org/exist/management/impl/JMXAgent.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 *
24
 * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
25
 *       The original license header is included below.
26
 *
27
 * =====================================================================
28
 *
29
 * eXist-db Open Source Native XML Database
30
 * Copyright (C) 2001 The eXist-db Authors
31
 *
32
 * info@exist-db.org
33
 * http://www.exist-db.org
34
 *
35
 * This library is free software; you can redistribute it and/or
36
 * modify it under the terms of the GNU Lesser General Public
37
 * License as published by the Free Software Foundation; either
38
 * version 2.1 of the License, or (at your option) any later version.
39
 *
40
 * This library is distributed in the hope that it will be useful,
41
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
42
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
43
 * Lesser General Public License for more details.
44
 *
45
 * You should have received a copy of the GNU Lesser General Public
46
 * License along with this library; if not, write to the Free Software
47
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
48
 */
49
package org.exist.management.impl;
50

51
import org.apache.logging.log4j.LogManager;
52
import org.apache.logging.log4j.Logger;
53
import org.exist.management.Agent;
54
import org.exist.management.TaskStatus;
55
import org.exist.storage.BrokerPool;
56
import org.exist.util.DatabaseConfigurationException;
57

58
import javax.management.InstanceAlreadyExistsException;
59
import javax.management.InstanceNotFoundException;
60
import javax.management.MBeanRegistrationException;
61
import javax.management.MBeanServer;
62
import javax.management.MalformedObjectNameException;
63
import javax.management.NotCompliantMBeanException;
64
import javax.management.ObjectName;
65
import java.lang.management.ManagementFactory;
66
import java.util.*;
67

68
/**
69
 * Real implementation of interface {@link org.exist.management.Agent}
70
 * which registers MBeans with the MBeanServer.
71
 *
72
 * Note that the agent will be constructed via reflection by the
73
 * {@link org.exist.management.AgentFactory}
74
 */
75
public final class JMXAgent implements Agent {
76

77
    private static final Logger LOG = LogManager.getLogger(JMXAgent.class);
1✔
78

79
    private final MBeanServer server;
80
    private final Map<String, Deque<ObjectName>> registeredMBeans = new HashMap<>();
1✔
81
    private final Map<ObjectName, Object> beanInstances = new HashMap<>();
1✔
82

83
    public JMXAgent() {
1✔
84
        if (LOG.isDebugEnabled()) {
1!
85
            LOG.debug("Creating the JMX MBeanServer.");
×
86
        }
87

88
        this.server = ManagementFactory.getPlatformMBeanServer();
1✔
89

90
        registerSystemMBeans();
1✔
91
    }
1✔
92

93
    private void registerSystemMBeans() {
94
        try {
95
            final SystemInfoMXBean systemInfoMXBean = new org.exist.management.impl.SystemInfo();
1✔
96
            addMBean(systemInfoMXBean.getName(), systemInfoMXBean);
1✔
97
        } catch (final MalformedObjectNameException | DatabaseConfigurationException e) {
1✔
98
            LOG.warn("Exception while registering cache mbean.", e);
×
99
        }
100
    }
1✔
101

102
    @Override
103
    public synchronized void initDBInstance(final BrokerPool instance) {
104
        final List<PerInstanceMBean> perInstanceMBeans = Arrays.asList(
1✔
105
                new Database(instance),
1✔
106
                new LockTable(instance),
1✔
107
                new SanityReport(instance),
1✔
108
                new DiskUsage(instance),
1✔
109
                new ProcessReport(instance),
1✔
110
                new BinaryValues(instance),
1✔
111
                new CollectionCache(instance)
1✔
112
        );
113

114
        for (final PerInstanceMBean perInstanceMBean : perInstanceMBeans) {
1✔
115
            try {
116
                addMBean(perInstanceMBean);
1✔
117
            } catch (final DatabaseConfigurationException e) {
1✔
118
                LOG.warn("Exception while registering JMX MBean: {}, for database: {}.", perInstanceMBean.getClass().getName(), instance.getId(), e);
×
119
            }
120
        }
121
    }
1✔
122

123
    @Override
124
    public synchronized void closeDBInstance(final BrokerPool instance) {
125
        final Deque<ObjectName> stack = registeredMBeans.get(instance.getId());
1✔
126
        while (!stack.isEmpty()) {
1✔
127
            final ObjectName on = stack.pop();
1✔
128
            if (LOG.isDebugEnabled()) {
1!
129
                LOG.debug("deregistering JMX MBean: {}", on);
×
130
            }
131
            beanInstances.remove(on);
1✔
132
            removeMBean(on);
1✔
133
        }
134
    }
1✔
135

136
    @Override
137
    public synchronized void addMBean(final PerInstanceMBean mbean) throws DatabaseConfigurationException {
138
        try {
139
            addMBean(mbean.getName(), mbean);
1✔
140
            if (mbean.getInstanceId() != null) {
1!
141
                Deque<ObjectName> stack = registeredMBeans.get(mbean.getInstanceId());
1✔
142
                if (stack == null) {
1✔
143
                    stack = new ArrayDeque<>();
1✔
144
                    registeredMBeans.put(mbean.getInstanceId(), stack);
1✔
145
                }
146
                stack.push(mbean.getName());
1✔
147
            }
148
            beanInstances.put(mbean.getName(), mbean);
1✔
149
        } catch (final MalformedObjectNameException e) {
1✔
150
            LOG.warn("Problem registering JMX MBean: {}", e.getMessage(), e);
×
151
            throw new DatabaseConfigurationException("Exception while registering JMX MBean: " + e.getMessage());
×
152
        }
153
    }
1✔
154

155
    private void addMBean(final ObjectName name, final Object mbean) throws DatabaseConfigurationException {
156
        try {
157
            if (!server.isRegistered(name)) {
1✔
158
                server.registerMBean(mbean, name);
1✔
159
            }
160

161
        } catch (final InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
1✔
162
            LOG.warn("Problem registering JMX MBean: {}", e.getMessage(), e);
×
163
            throw new DatabaseConfigurationException("Exception while registering JMX MBean: " + e.getMessage());
×
164
        }
165
    }
1✔
166

167
    private void removeMBean(final ObjectName name) {
168
        try {
169
            if (server.isRegistered(name)) {
1✔
170
                server.unregisterMBean(name);
1✔
171
            }
172
        } catch (final InstanceNotFoundException | MBeanRegistrationException  e) {
1✔
173
            LOG.warn("Problem unregistering mbean: {}", e.getMessage(), e);
×
174
        }
175
    }
1✔
176

177
    @Override
178
    public synchronized void changeStatus(final BrokerPool instance, final TaskStatus actualStatus) {
179
        try {
180
            final ObjectName name = new ObjectName("org.exist.management." + instance.getId() + ".tasks:type=SanityReport");
1✔
181
            final SanityReport report = (SanityReport) beanInstances.get(name);
1✔
182
            if (report != null) {
1!
183
                report.changeStatus(actualStatus);
×
184
            }
185
        } catch (final MalformedObjectNameException e) {
×
186
            LOG.warn("Problem calling JMX MBean: {}", e.getMessage(), e);
×
187
        }
188
    }
1✔
189

190
    @Override
191
    public synchronized void updateStatus(final BrokerPool instance, final int percentage) {
192
        try {
193
            final ObjectName name = new ObjectName("org.exist.management." + instance.getId() + ".tasks:type=SanityReport");
1✔
194
            final SanityReport report = (SanityReport) beanInstances.get(name);
1✔
195
            if (report != null) {
1✔
196
                report.updateStatus(percentage);
1✔
197
            }
198
        } catch (final MalformedObjectNameException e) {
1✔
199
            LOG.warn("Problem calling JMX MBean: {}", e.getMessage(), e);
×
200
        }
201
    }
1✔
202
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc