Skip to content

Commit

Permalink
WFLY-12165 Expose management metrics for HotRod caches
Browse files Browse the repository at this point in the history
  • Loading branch information
pferraro committed Aug 6, 2019
1 parent ed119d7 commit 06001ac
Show file tree
Hide file tree
Showing 19 changed files with 853 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;

import javax.transaction.TransactionManager;

import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.configuration.Configuration;
import org.infinispan.client.hotrod.configuration.NearCacheConfiguration;
import org.infinispan.client.hotrod.configuration.TransactionMode;
import org.infinispan.client.hotrod.event.impl.ClientListenerNotifier;
import org.infinispan.client.hotrod.near.NearCacheService;
import org.wildfly.clustering.Registrar;
import org.wildfly.clustering.infinispan.client.RegisteredRemoteCache;
import org.wildfly.clustering.infinispan.client.RemoteCacheContainer;

/**
Expand All @@ -41,17 +47,24 @@ public class RemoteCacheManager extends org.infinispan.client.hotrod.RemoteCache

private final Map<String, Function<ClientListenerNotifier, NearCacheService<?, ?>>> nearCacheFactories = new ConcurrentHashMap<>();
private final String name;
private final Registrar<String> registrar;

public RemoteCacheManager(String name, Configuration configuration) {
public RemoteCacheManager(String name, Configuration configuration, Registrar<String> registrar) {
super(configuration, false);
this.name = name;
this.registrar = registrar;
}

@Override
public String getName() {
return this.name;
}

@Override
public <K, V> RemoteCache<K, V> getCache(String cacheName, boolean forceReturnValue, TransactionMode transactionMode, TransactionManager transactionManager) {
return new RegisteredRemoteCache<>(this, super.getCache(cacheName, forceReturnValue, transactionMode, transactionManager), this.registrar);
}

@SuppressWarnings("unchecked")
@Override
public <K, V> NearCacheRegistration registerNearCacheFactory(String cacheName, Function<ClientListenerNotifier, NearCacheService<K, V>> factory) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,12 @@ private void parseRemoteContainer(XMLExtendedStreamReader reader, PathAddress su
readAttribute(reader, i, operation, RemoteCacheContainerResourceDefinition.Attribute.VALUE_SIZE_ESTIMATE);
break;
}
case STATISTICS_ENABLED: {
if (this.schema.since(InfinispanSchema.VERSION_9_0)) {
readAttribute(reader, i, operation, RemoteCacheContainerResourceDefinition.Attribute.STATISTICS_ENABLED);
break;
}
}
default: {
throw ParseUtils.unexpectedAttribute(reader, i);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.util.function.Function;
import java.util.function.Supplier;

import javax.management.MBeanServer;

import org.infinispan.client.hotrod.ProtocolVersion;
import org.infinispan.client.hotrod.configuration.ClusterConfigurationBuilder;
import org.infinispan.client.hotrod.configuration.Configuration;
Expand All @@ -41,8 +43,10 @@
import org.infinispan.client.hotrod.configuration.SecurityConfiguration;
import org.infinispan.client.hotrod.configuration.TransactionConfiguration;
import org.jboss.as.clustering.controller.CapabilityServiceNameProvider;
import org.jboss.as.clustering.controller.CommonRequirement;
import org.jboss.as.clustering.controller.CommonUnaryRequirement;
import org.jboss.as.clustering.controller.ResourceServiceConfigurator;
import org.jboss.as.clustering.infinispan.MBeanServerProvider;
import org.jboss.as.clustering.infinispan.subsystem.ThreadPoolResourceDefinition;
import org.jboss.as.clustering.infinispan.subsystem.remote.RemoteCacheContainerResourceDefinition.Attribute;
import org.jboss.as.controller.OperationContext;
Expand All @@ -66,6 +70,7 @@

/**
* @author Radoslav Husar
* @author Paul Ferraro
*/
public class RemoteCacheContainerConfigurationServiceConfigurator extends CapabilityServiceNameProvider implements ResourceServiceConfigurator, Supplier<Configuration> {

Expand All @@ -77,6 +82,7 @@ public class RemoteCacheContainerConfigurationServiceConfigurator extends Capabi
private final SupplierDependency<SecurityConfiguration> security;
private final SupplierDependency<TransactionConfiguration> transaction;

private volatile SupplierDependency<MBeanServer> server;
private volatile int connectionTimeout;
private volatile String defaultRemoteCluster;
private volatile int keySizeEstimate;
Expand All @@ -86,6 +92,7 @@ public class RemoteCacheContainerConfigurationServiceConfigurator extends Capabi
private volatile boolean tcpNoDelay;
private volatile boolean tcpKeepAlive;
private volatile int valueSizeEstimate;
private volatile boolean statisticsEnabled;

RemoteCacheContainerConfigurationServiceConfigurator(PathAddress address) {
super(RemoteCacheContainerResourceDefinition.Capability.CONFIGURATION, address);
Expand All @@ -108,6 +115,7 @@ public ServiceConfigurator configure(OperationContext context, ModelNode model)
this.tcpNoDelay = Attribute.TCP_NO_DELAY.resolveModelAttribute(context, model).asBoolean();
this.tcpKeepAlive = Attribute.TCP_KEEP_ALIVE.resolveModelAttribute(context, model).asBoolean();
this.valueSizeEstimate = Attribute.VALUE_SIZE_ESTIMATE.resolveModelAttribute(context, model).asInt();
this.statisticsEnabled = Attribute.STATISTICS_ENABLED.resolveModelAttribute(context, model).asBoolean();

this.clusters.clear();

Expand All @@ -123,13 +131,15 @@ public ServiceConfigurator configure(OperationContext context, ModelNode model)
this.clusters.put(clusterName, bindingDependencies);
}

this.server = context.hasOptionalCapability(CommonRequirement.MBEAN_SERVER.getName(), null, null) ? new ServiceSupplierDependency<>(CommonRequirement.MBEAN_SERVER.getServiceName(context)) : null;

return this;
}

@Override
public ServiceBuilder<?> build(ServiceTarget target) {
ServiceBuilder<?> builder = target.addService(this.getServiceName());
Consumer<Configuration> configuration = new CompositeDependency(this.module, this.connectionPool, this.nearCache, this.security, this.transaction).register(builder).provides(this.getServiceName());
Consumer<Configuration> configuration = new CompositeDependency(this.module, this.connectionPool, this.nearCache, this.security, this.transaction, this.server).register(builder).provides(this.getServiceName());
for (Dependency dependency : this.threadPools.values()) {
dependency.register(builder);
}
Expand All @@ -144,13 +154,19 @@ public ServiceBuilder<?> build(ServiceTarget target) {

@Override
public Configuration get() {
MBeanServer server = (this.server != null) ? this.server.get() : null;
ConfigurationBuilder builder = new ConfigurationBuilder()
.marshaller(new HotRodMarshaller(this.module.get()))
.connectionTimeout(this.connectionTimeout)
.keySizeEstimate(this.keySizeEstimate)
.maxRetries(this.maxRetries)
.version(ProtocolVersion.parseVersion(this.protocolVersion))
.socketTimeout(this.socketTimeout)
.statistics()
.enabled(this.statisticsEnabled)
.jmxDomain("org.wildfly.clustering.infinispan")
.jmxEnabled(server != null)
.mBeanServerLookup(new MBeanServerProvider(server))
.tcpNoDelay(this.tcpNoDelay)
.tcpKeepAlive(this.tcpKeepAlive)
.valueSizeEstimate(this.valueSizeEstimate);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2019, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.clustering.infinispan.subsystem.remote;

import java.util.function.ToIntFunction;

import org.infinispan.client.hotrod.jmx.RemoteCacheManagerMXBean;
import org.jboss.as.clustering.controller.Metric;
import org.jboss.as.clustering.infinispan.subsystem.InfinispanModel;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.registry.AttributeAccess;
import org.jboss.as.controller.transform.description.DiscardAttributeChecker;
import org.jboss.as.controller.transform.description.ResourceTransformationDescriptionBuilder;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;

/**
* @author Paul Ferraro
*/
public enum RemoteCacheContainerMetric implements Metric<RemoteCacheManagerMXBean>, ToIntFunction<RemoteCacheManagerMXBean> {

ACTIVE_CONNECTIONS("active-connections") {
@Override
public int applyAsInt(RemoteCacheManagerMXBean manager) {
return manager.getActiveConnectionCount();
}
},
CONNECTIONS("connections") {
@Override
public int applyAsInt(RemoteCacheManagerMXBean manager) {
return manager.getConnectionCount();
}
},
IDLE_CONNECTIONS("idle-connections") {
@Override
public int applyAsInt(RemoteCacheManagerMXBean manager) {
return manager.getIdleConnectionCount();
}
}
;
static void buildTransformation(ModelVersion version, ResourceTransformationDescriptionBuilder builder) {
if (InfinispanModel.VERSION_11_0_0.requiresTransformation(version)) {
builder.getAttributeBuilder().setDiscard(DiscardAttributeChecker.ALWAYS, ACTIVE_CONNECTIONS.getName(), CONNECTIONS.getName(), IDLE_CONNECTIONS.getName());
}
}

private final AttributeDefinition definition;

RemoteCacheContainerMetric(String name) {
this.definition = new SimpleAttributeDefinitionBuilder(name, ModelType.INT)
.setFlags(AttributeAccess.Flag.GAUGE_METRIC)
.setStorageRuntime()
.build();
}

@Override
public AttributeDefinition getDefinition() {
return this.definition;
}

@Override
public ModelNode execute(RemoteCacheManagerMXBean manager) throws OperationFailedException {
return new ModelNode(this.applyAsInt(manager));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2019, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.clustering.infinispan.subsystem.remote;

import org.infinispan.client.hotrod.jmx.RemoteCacheManagerMXBean;
import org.jboss.as.clustering.controller.Metric;
import org.jboss.as.clustering.controller.MetricExecutor;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.PathAddress;
import org.jboss.dmr.ModelNode;
import org.wildfly.clustering.infinispan.client.InfinispanClientRequirement;
import org.wildfly.clustering.infinispan.client.RemoteCacheContainer;
import org.wildfly.clustering.service.PassiveServiceSupplier;

/**
* @author Paul Ferraro
*/
public class RemoteCacheContainerMetricExecutor implements MetricExecutor<RemoteCacheManagerMXBean> {

@Override
public ModelNode execute(OperationContext context, Metric<RemoteCacheManagerMXBean> metric) throws OperationFailedException {
PathAddress address = context.getCurrentAddress();
String name = address.getLastElement().getValue();

RemoteCacheContainer container = new PassiveServiceSupplier<RemoteCacheContainer>(context.getServiceRegistry(true), InfinispanClientRequirement.REMOTE_CONTAINER.getServiceName(context, name)).get();
return (container != null) ? metric.execute(container) : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2019, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

package org.jboss.as.clustering.infinispan.subsystem.remote;

import org.infinispan.client.hotrod.jmx.RemoteCacheManagerMXBean;
import org.jboss.as.clustering.controller.Operation;
import org.jboss.as.clustering.infinispan.subsystem.InfinispanExtension;
import org.jboss.as.clustering.infinispan.subsystem.InfinispanModel;
import org.jboss.as.controller.AttributeDefinition;
import org.jboss.as.controller.ExpressionResolver;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationDefinition;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
import org.jboss.as.controller.SimpleOperationDefinitionBuilder;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.transform.description.ResourceTransformationDescriptionBuilder;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;

/**
* @author Paul Ferraro
*/
public enum RemoteCacheContainerOperation implements Operation<RemoteCacheManagerMXBean> {

SWITCH_CLUSTER("switch-cluster", ModelType.BOOLEAN) {
private final AttributeDefinition name = new SimpleAttributeDefinitionBuilder(ModelDescriptionConstants.NAME, ModelType.STRING)
.setRequired(true)
.build();

@Override
public ModelNode execute(ExpressionResolver resolver, ModelNode operation, RemoteCacheManagerMXBean manager) throws OperationFailedException {
String name = operation.get(this.name.getName()).asString();
return new ModelNode(manager.switchToCluster(name));
}

@Override
public AttributeDefinition[] getParameters() {
return new AttributeDefinition[] { this.name };
}
},
;
static void buildTransformation(ModelVersion version, ResourceTransformationDescriptionBuilder builder) {
if (InfinispanModel.VERSION_11_0_0.requiresTransformation(version)) {
builder.discardOperations(SWITCH_CLUSTER.getName());
}
}

private final OperationDefinition definition;

RemoteCacheContainerOperation(String name, ModelType replyType) {
this.definition = new SimpleOperationDefinitionBuilder(name, InfinispanExtension.SUBSYSTEM_RESOLVER.createChildResolver(RemoteCacheResourceDefinition.WILDCARD_PATH))
.setParameters(this.getParameters())
.setReplyType(replyType)
.setRuntimeOnly()
.build();
}

@Override
public OperationDefinition getDefinition() {
return this.definition;
}
}

0 comments on commit 06001ac

Please sign in to comment.