Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 66 additions & 11 deletions src/main/java/org/weakref/jmx/MBeanExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class MBeanExporter
private final MBeanServer server;
private final Map<ObjectName, Object> exportedObjects;
private final ObjectNameGenerator objectNameGenerator;
private final Map<ObjectName, ManagedClass> exportedManagedClasses = new ConcurrentHashMap<>();
private final Map<ObjectName, ManagedObjectExport> exportedManagedObjectExports = new ConcurrentHashMap<>();

public MBeanExporter(MBeanServer server)
{
Expand Down Expand Up @@ -74,8 +74,9 @@ public void destroy()
public MBeanExport exportWithGeneratedName(Object object)
{
requireNonNull(object, "object is null");
ObjectName objectName = createObjectName(objectNameGenerator.generatedNameOf(object.getClass()));
export(objectName, object);
Class<?> type = object.getClass();
ObjectName objectName = createObjectName(objectNameGenerator.generatedNameOf(type));
export(objectName, object, Optional.of(type), Optional.empty(), ImmutableMap.of());
return new MBeanExport(objectName, () -> unexport(objectName));
}

Expand All @@ -84,7 +85,16 @@ public MBeanExport exportWithGeneratedName(Object object, Class<?> type)
requireNonNull(object, "object is null");
requireNonNull(type, "type is null");
ObjectName objectName = createObjectName(objectNameGenerator.generatedNameOf(type));
export(objectName, object);
export(objectName, object, Optional.of(type), Optional.empty(), ImmutableMap.of());
return new MBeanExport(objectName, () -> unexport(objectName));
}

public MBeanExport exportWithGeneratedName(ObjectName objectName, Object object, Class<?> type)
{
requireNonNull(objectName, "objectName is null");
requireNonNull(object, "object is null");
requireNonNull(type, "type is null");
export(objectName, object, Optional.of(type), Optional.empty(), ImmutableMap.of());
return new MBeanExport(objectName, () -> unexport(objectName));
}

Expand All @@ -94,7 +104,17 @@ public MBeanExport exportWithGeneratedName(Object object, Class<?> type, String
requireNonNull(type, "type is null");
requireNonNull(name, "name is null");
ObjectName objectName = createObjectName(objectNameGenerator.generatedNameOf(type, name));
export(objectName, object);
export(objectName, object, Optional.of(type), Optional.of(name), ImmutableMap.of());
return new MBeanExport(objectName, () -> unexport(objectName));
}

public MBeanExport exportWithGeneratedName(ObjectName objectName, Object object, Class<?> type, String name)
{
requireNonNull(objectName, "objectName is null");
requireNonNull(object, "object is null");
requireNonNull(type, "type is null");
requireNonNull(name, "name is null");
export(objectName, object, Optional.of(type), Optional.of(name), ImmutableMap.of());
return new MBeanExport(objectName, () -> unexport(objectName));
}

Expand All @@ -104,7 +124,7 @@ public MBeanExport exportWithGeneratedName(Object object, Class<?> type, Map<Str
requireNonNull(type, "type is null");
requireNonNull(properties, "properties is null");
ObjectName objectName = createObjectName(objectNameGenerator.generatedNameOf(type, properties));
export(objectName, object);
export(objectName, object, Optional.of(type), Optional.empty(), properties);
return new MBeanExport(objectName, () -> unexport(objectName));
}

Expand All @@ -113,8 +133,34 @@ public void export(String name, Object object)
export(createObjectName(name), object);
}

public void export(String name, Object object, Class<?> type)
{
export(createObjectName(name), object, type);
}

public void export(ObjectName objectName, Object object)
{
export(objectName, object, Optional.empty(), Optional.empty(), ImmutableMap.of());
}

public void export(ObjectName objectName, Object object, Class<?> type)
{
requireNonNull(type, "type is null");
export(objectName, object, Optional.of(type), Optional.empty(), ImmutableMap.of());
}

private void export(
ObjectName objectName,
Object object,
Optional<Class<?>> exportedType,
Optional<String> originalName,
Map<String, String> originalProperties)
{
requireNonNull(objectName, "objectName is null");
requireNonNull(object, "object is null");
requireNonNull(exportedType, "exportedType is null");
requireNonNull(originalName, "originalName is null");
requireNonNull(originalProperties, "originalProperties is null");
try {
MBeanBuilder builder = new MBeanBuilder(object);
MBean mbean = builder.build();
Expand All @@ -127,7 +173,8 @@ public void export(ObjectName objectName, Object object)
exportedObjects.put(objectName, object);
}

exportedManagedClasses.put(objectName, ManagedClass.fromExportedObject(object));
ManagedClass managedClass = ManagedClass.fromExportedObject(object);
exportedManagedObjectExports.put(objectName, new ManagedObjectExport(objectName, exportedType, originalName, originalProperties, managedClass));
}
catch (InstanceAlreadyExistsException e) {
throw new JmxException(Reason.INSTANCE_ALREADY_EXISTS, e.getMessage());
Expand Down Expand Up @@ -174,7 +221,7 @@ public void unexport(ObjectName objectName)
exportedObjects.remove(objectName);
}

exportedManagedClasses.remove(objectName);
exportedManagedObjectExports.remove(objectName);
}
catch (MBeanRegistrationException e) {
throw new JmxException(Reason.MBEAN_REGISTRATION, e.getMessage(), e.getCause());
Expand Down Expand Up @@ -220,7 +267,7 @@ public Map<String, Exception> unexportAllAndReportMissing()

exportedObjects.keySet().removeAll(toRemove);

exportedManagedClasses.keySet().removeAll(toRemove);
exportedManagedObjectExports.keySet().removeAll(toRemove);
}

return errors;
Expand All @@ -240,12 +287,20 @@ public Map<String, Object> getExportedObjects()
public Map<String, ManagedClass> getManagedClasses()
{
ImmutableMap.Builder<String, ManagedClass> builder = ImmutableMap.builder();
for (Entry<ObjectName, ManagedClass> entry : exportedManagedClasses.entrySet()) {
builder.put(entry.getKey().toString(), entry.getValue());
for (Entry<ObjectName, ManagedObjectExport> entry : exportedManagedObjectExports.entrySet()) {
builder.put(entry.getKey().toString(), entry.getValue().getManagedClass());
}
return builder.build();
}

/**
* Returns metadata for managed objects exported through this exporter, keyed by final {@link ObjectName}.
*/
public Map<ObjectName, ManagedObjectExport> getManagedObjectExports()
{
return ImmutableMap.copyOf(exportedManagedObjectExports);
}

public Optional<Object> getExportedObject(ObjectName objectName)
{
synchronized (exportedObjects) {
Expand Down
85 changes: 85 additions & 0 deletions src/main/java/org/weakref/jmx/ManagedObjectExport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Copyright 2009 Martin Traverso
*
* 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.weakref.jmx;

import com.google.common.collect.ImmutableMap;

import javax.management.ObjectName;

import java.util.Map;
import java.util.Optional;

import static java.util.Objects.requireNonNull;

/**
* Metadata for a managed object exported through an {@link MBeanExporter}.
*/
public final class ManagedObjectExport
{
private final ObjectName objectName;
private final Optional<Class<?>> exportedType;
private final Optional<String> originalName;
private final Map<String, String> originalProperties;
private final ManagedClass managedClass;

ManagedObjectExport(
ObjectName objectName,
Optional<Class<?>> exportedType,
Optional<String> originalName,
Map<String, String> originalProperties,
ManagedClass managedClass)
{
this.objectName = requireNonNull(objectName, "objectName is null");
this.exportedType = requireNonNull(exportedType, "exportedType is null");
this.originalName = requireNonNull(originalName, "originalName is null");
this.originalProperties = ImmutableMap.copyOf(requireNonNull(originalProperties, "originalProperties is null"));
this.managedClass = requireNonNull(managedClass, "managedClass is null");
}

public ObjectName getObjectName()
{
return objectName;
}

/**
* Original Java type supplied when the object was exported, if one was available.
*/
public Optional<Class<?>> getExportedType()
{
return exportedType;
}

/**
* Original name argument passed to the {@link ObjectNameGenerator}, if any.
*/
public Optional<String> getOriginalName()
{
return originalName;
}

/**
* Original properties map passed to the {@link ObjectNameGenerator}, if any.
*/
public Map<String, String> getOriginalProperties()
{
return originalProperties;
}

public ManagedClass getManagedClass()
{
return managedClass;
}
}
16 changes: 3 additions & 13 deletions src/main/java/org/weakref/jmx/guice/GuiceMBeanExporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@
import org.weakref.jmx.MBeanExporter;
import org.weakref.jmx.ObjectNameGenerator;

import javax.management.ObjectName;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiFunction;

class GuiceMBeanExporter
{
Expand Down Expand Up @@ -61,35 +57,29 @@ private static Set<SetMapping<Object>> castSetMapping(Object setMappings)
private static <K, V> void exportMaps(Set<MapMapping<K, V>> mapMappings, MBeanExporter exporter, Injector injector, ObjectNameGenerator objectNameGenerator)
{
for (MapMapping<K, V> mapping : mapMappings) {
BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> namingFunction = mapping.getObjectNameFunction();

Map<K, V> map = injector.getInstance(mapping.getKey());

for (Map.Entry<K, V> entry : map.entrySet()) {
ObjectName name = namingFunction.apply(objectNameGenerator, entry);
exporter.export(name, entry.getValue());
mapping.export(exporter, objectNameGenerator, entry);
}
}
}

private static <T> void exportSets(Set<SetMapping<T>> setMappings, MBeanExporter exporter, Injector injector, ObjectNameGenerator objectNameGenerator)
{
for (SetMapping<T> mapping : setMappings) {
BiFunction<ObjectNameGenerator, T, ObjectName> namingFunction = mapping.getObjectNameFunction();

Set<T> set = injector.getInstance(mapping.getKey());

for (T instance : set) {
ObjectName name = namingFunction.apply(objectNameGenerator, instance);
exporter.export(name, instance);
mapping.export(exporter, objectNameGenerator, instance);
}
}
}

private static void export(Set<Mapping> mappings, MBeanExporter exporter, Injector injector, ObjectNameGenerator objectNameGenerator)
{
for (Mapping mapping : mappings) {
exporter.export(mapping.getName(objectNameGenerator), injector.getInstance(mapping.getKey()));
mapping.export(exporter, objectNameGenerator, injector.getInstance(mapping.getKey()));
}
}
}
25 changes: 2 additions & 23 deletions src/main/java/org/weakref/jmx/guice/MapExportBinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.google.inject.multibindings.Multibinder;
import org.weakref.jmx.ObjectNameGenerator;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import java.util.Map.Entry;
Expand All @@ -24,17 +23,7 @@ public class MapExportBinder<K, V>

public void withGeneratedName(NamingFunction<V> valueNamingFunction)
{
BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> nameFactory = (factory, entry) -> {
try {
String itemName = valueNamingFunction.name(entry.getValue());
return new ObjectName(factory.generatedNameOf(valueClass, itemName));
}
catch (MalformedObjectNameException e) {
throw new RuntimeException(e);
}
};

as(nameFactory);
binder.addBinding().toInstance(MapMapping.generatedName(keyClass, valueClass, (key, value) -> valueNamingFunction.name(value)));
}

public void withGeneratedName(ObjectNameFunction<V> valueNamingFunction)
Expand All @@ -44,17 +33,7 @@ public void withGeneratedName(ObjectNameFunction<V> valueNamingFunction)

public void withGeneratedName(MapNamingFunction<K, V> valueNamingFunction)
{
BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> nameFactory = (factory, entry) -> {
try {
String itemName = valueNamingFunction.name(entry.getKey(), entry.getValue());
return new ObjectName(factory.generatedNameOf(valueClass, itemName));
}
catch (MalformedObjectNameException e) {
throw new RuntimeException(e);
}
};

as(nameFactory);
binder.addBinding().toInstance(MapMapping.generatedName(keyClass, valueClass, valueNamingFunction));
}

public void withGeneratedName(MapObjectNameFunction<K, V> valueNamingFunction)
Expand Down
28 changes: 24 additions & 4 deletions src/main/java/org/weakref/jmx/guice/MapMapping.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.weakref.jmx.guice;

import com.google.inject.Key;
import org.weakref.jmx.MBeanExporter;
import org.weakref.jmx.ObjectNameGenerator;

import javax.management.ObjectName;
Expand All @@ -13,25 +14,44 @@

class MapMapping<K, V>
{
private final BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> objectNameFunction;
private final Class<K> keyClass;
private final Class<V> valueClass;
private final ExportAction<K, V> exportAction;

MapMapping(Class<K> keyClass, Class<V> valueClass, BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> objectNameFunction)
{
this(keyClass, valueClass, (exporter, objectNameGenerator, entry) -> exporter.export(objectNameFunction.apply(objectNameGenerator, entry), entry.getValue(), valueClass));
}

private MapMapping(Class<K> keyClass, Class<V> valueClass, ExportAction<K, V> exportAction)
{
this.keyClass = keyClass;
this.valueClass = valueClass;
this.objectNameFunction = objectNameFunction;
this.exportAction = exportAction;
}

public BiFunction<ObjectNameGenerator, Entry<K, V>, ObjectName> getObjectNameFunction()
public static <K, V> MapMapping<K, V> generatedName(Class<K> keyClass, Class<V> valueClass, MapNamingFunction<K, V> namingFunction)
{
return objectNameFunction;
return new MapMapping<>(keyClass, valueClass, (exporter, objectNameGenerator, entry) -> {
String name = namingFunction.name(entry.getKey(), entry.getValue());
ObjectName objectName = Mapping.createObjectName(objectNameGenerator.generatedNameOf(valueClass, name));
exporter.exportWithGeneratedName(objectName, entry.getValue(), valueClass, name);
});
}

@SuppressWarnings("unchecked")
public Key<Map<K, V>> getKey()
{
return (Key<Map<K, V>>) Key.get(mapOf(keyClass, valueClass));
}

public void export(MBeanExporter exporter, ObjectNameGenerator objectNameGenerator, Entry<K, V> entry)
{
exportAction.export(exporter, objectNameGenerator, entry);
}

private interface ExportAction<K, V>
{
void export(MBeanExporter exporter, ObjectNameGenerator objectNameGenerator, Entry<K, V> entry);
}
}
Loading
Loading