/* * Copyright 2015-2017 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hawkular.agent.monitor.protocol.dmr; import java.util.Collections; import java.util.List; import org.hawkular.agent.monitor.log.AgentLoggers; import org.hawkular.agent.monitor.log.MsgLogger; import org.hawkular.agent.monitor.util.WildflyCompatibilityUtils; import org.hawkular.dmr.api.OperationBuilder; import org.hawkular.dmr.api.OperationBuilder.CompositeOperationBuilder; import org.hawkular.dmr.api.OperationBuilder.OperationResult; import org.jboss.as.controller.PathAddress; import org.jboss.as.controller.client.ModelControllerClient; /** * Turns on or off statistics for several WildFly subsystems. */ public class StatisticsControl { private static final MsgLogger log = AgentLoggers.getLogger(StatisticsControl.class); public StatisticsControl() { } public void enableStatistics(ModelControllerClient mcc) { execute(mcc, true); } public void disableStatistics(ModelControllerClient mcc) { execute(mcc, false); } private void execute(ModelControllerClient mcc, boolean enable) { try { List<String> hosts = getDomainHosts(mcc); if (hosts.isEmpty()) { executeForServer(mcc, enable, ""); } else { for (String host : hosts) { List<String> servers = getDomainHostServers(mcc, host); for (String server : servers) { // I was trying to be too clever. This would work awesomely if WildFly would just allow it. // However, this error occurs when you try to set attributes on slave servers: // "User operations are not permitted to directly update the persistent configuration // of a server in a managed domain." // So, for now, comment this out until perhaps in the future WildFly/EAP will allow this. // This means when in domain mode, the user must manually turn on statistics themselves. //executeForServer(mcc, enable, String.format("/host=%s/server=%s", host, server)); log.debugf("Statistics for server [/host=%s/server=%s] must be enabled manually", host, server); } } } } catch (Exception e) { log.errorf(e, "Aborting statistics enablement"); } } private void executeForServer(ModelControllerClient mcc, boolean enable, String serverPrefix) { try { String enableStr = String.valueOf(enable); CompositeOperationBuilder<?> batch; // datasources batch = OperationBuilder.composite(); List<String> dsList = getChildrenNames( WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=datasources"), "data-source", mcc); List<String> xaList = getChildrenNames( WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=datasources"), "xa-data-source", mcc); for (String ds : dsList) { String dsAddr = String.format(serverPrefix + "/subsystem=datasources/data-source=%s", ds); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(dsAddr)) .attribute("statistics-enabled", enableStr) .parentBuilder(); } for (String xa : xaList) { String xaAddr = String.format(serverPrefix + "/subsystem=datasources/xa-data-source=%s", xa); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(xaAddr)) .attribute("statistics-enabled", enableStr) .parentBuilder(); } execute(mcc, batch, "datasources", enable); // ejb3 batch = OperationBuilder.composite(); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=ejb3")) .attribute("enable-statistics", enableStr) .parentBuilder(); execute(mcc, batch, "ejb3", enable); // infinispan batch = OperationBuilder.composite(); List<String> infinispanList = getChildrenNames( WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=infinispan"), "cache-container", mcc); for (String name : infinispanList) { String addr = String.format(serverPrefix + "/subsystem=infinispan/cache-container=%s", name); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(addr)) .attribute("statistics-enabled", enableStr) .parentBuilder(); } execute(mcc, batch, "infinispan", enable); // activemq batch = OperationBuilder.composite(); List<String> activeMqList = getChildrenNames( WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=messaging-activemq"), "server", mcc); for (String name : activeMqList) { String addr = String.format(serverPrefix + "/subsystem=messaging-activemq/server=%s", name); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(addr)) .attribute("statistics-enabled", enableStr) .parentBuilder(); } execute(mcc, batch, "activemq", enable); // transactions batch = OperationBuilder.composite(); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=transactions")) .attribute("enable-statistics", enableStr) .parentBuilder(); execute(mcc, batch, "transactions", enable); // undertow batch = OperationBuilder.composite(); batch.writeAttribute() .address(WildflyCompatibilityUtils.parseCLIStyleAddress(serverPrefix + "/subsystem=undertow")) .attribute("statistics-enabled", enableStr) .parentBuilder(); execute(mcc, batch, "undertow", enable); } catch (Exception e) { log.errorf(e, "Aborting statistics enablement"); } } private void execute(ModelControllerClient controllerClient, CompositeOperationBuilder<?> batch, String name, boolean enable) { OperationResult<?> opResult = null; try { opResult = batch.execute(controllerClient).assertSuccess(); log.debugf("%s statistics for [%s]", enable ? "Enabled" : "Disabled", name); } catch (Exception e) { String errorStr = (opResult != null) ? opResult.getResultNode().toJSONString(true) : "unknown result"; log.debugf(e, "Cannot set statistics for [%s]: %s", name, errorStr); } } private List<String> getChildrenNames(PathAddress parentPath, String childType, ModelControllerClient mcc) { try { return OperationBuilder.readChildrenNames() .address(parentPath) .childType(childType) .execute(mcc) .assertSuccess() .getList(); } catch (Exception e) { log.debugf("Cannot get children of [" + parentPath + "] of type [" + childType + "]"); return Collections.emptyList(); } } // returns empty list if not in domain mode private List<String> getDomainHosts(ModelControllerClient mcc) { return getChildrenNames(PathAddress.EMPTY_ADDRESS, "host", mcc); } // returns empty list if not in domain mode private List<String> getDomainHostServers(ModelControllerClient mcc, String hostName) { return getChildrenNames(PathAddress.EMPTY_ADDRESS.append("host", hostName), "server", mcc); } }