package org.springframework.boot.actuate.endpoint.jmx;
import java.util.List;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanConstructorInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanNotificationInfo;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import org.springframework.boot.actuate.endpoint.OperationType;
class MBeanInfoFactory {
private static final ModelMBeanAttributeInfo[] NO_ATTRIBUTES = new ModelMBeanAttributeInfo[0];
private static final ModelMBeanConstructorInfo[] NO_CONSTRUCTORS = new ModelMBeanConstructorInfo[0];
private static final ModelMBeanNotificationInfo[] NO_NOTIFICATIONS = new ModelMBeanNotificationInfo[0];
private final JmxOperationResponseMapper responseMapper;
MBeanInfoFactory(JmxOperationResponseMapper responseMapper) {
this.responseMapper = responseMapper;
}
MBeanInfo getMBeanInfo(ExposableJmxEndpoint endpoint) {
String className = EndpointMBean.class.getName();
String description = getDescription(endpoint);
ModelMBeanOperationInfo[] operations = getMBeanOperations(endpoint);
return new ModelMBeanInfoSupport(className, description, NO_ATTRIBUTES, NO_CONSTRUCTORS, operations,
NO_NOTIFICATIONS);
}
private String getDescription(ExposableJmxEndpoint endpoint) {
return "MBean operations for endpoint " + endpoint.getEndpointId();
}
private ModelMBeanOperationInfo[] getMBeanOperations(ExposableJmxEndpoint endpoint) {
return endpoint.getOperations().stream().map(this::getMBeanOperation).toArray(ModelMBeanOperationInfo[]::new);
}
private ModelMBeanOperationInfo getMBeanOperation(JmxOperation operation) {
String name = operation.getName();
String description = operation.getDescription();
MBeanParameterInfo[] signature = getSignature(operation.getParameters());
String type = getType(operation.getOutputType());
int impact = getImpact(operation.getType());
return new ModelMBeanOperationInfo(name, description, signature, type, impact);
}
private MBeanParameterInfo[] getSignature(List<JmxOperationParameter> parameters) {
return parameters.stream().map(this::getMBeanParameter).toArray(MBeanParameterInfo[]::new);
}
private MBeanParameterInfo getMBeanParameter(JmxOperationParameter parameter) {
return new MBeanParameterInfo(parameter.getName(), parameter.getType().getName(), parameter.getDescription());
}
private int getImpact(OperationType operationType) {
if (operationType == OperationType.READ) {
return MBeanOperationInfo.INFO;
}
if (operationType == OperationType.WRITE || operationType == OperationType.DELETE) {
return MBeanOperationInfo.ACTION;
}
return MBeanOperationInfo.UNKNOWN;
}
private String getType(Class<?> outputType) {
return this.responseMapper.mapResponseType(outputType).getName();
}
}