org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.brooklyn.entity.software.base.test.jmx;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Map;
import java.util.Map.Entry;

import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.DynamicMBean;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanConstructorInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;

/**
 * A quick-and-simple general-purpose implementation of DynamicMBean.
 *
 * This class provides an implementation of {@link DynamicMBean}. Its initial set of attribute names and values are
 * provided to the constructor; from this it figures an {@link MBeanInfo}.
 * <p>
 * It presently assumes that all attributes are read-only; operations and notifications are not currently supported.
 * Choosing the descriptions is not supported - they are set to be the same as the name.
 * <p>
 * Getting a valid dynamic MBean (in Groovy) is as simple as:
 * <pre>
 * new GeneralisedDynamicMBean(meaning: 42, advice: "Don't panic")
 * </pre>
 */
public class GeneralisedDynamicMBean implements DynamicMBean {
    private final MBeanInfo mBeanInfo;
    private final Map<String, Object> attributes = Maps.newLinkedHashMap();
    private final Map<String, Function> operations = Maps.newLinkedHashMap();

    public GeneralisedDynamicMBean(Map<String, ?> initialAttributes, Map<?, ?> initialOperations) {
        attributes.putAll(initialAttributes);

        for (Entry<?, ?> entry : initialOperations.entrySet()) {
            checkArgument(entry.getKey() instanceof String || entry.getKey() instanceof MBeanOperationInfo,
                    "entry.key=%s", entry.getKey());
            String opName = (entry.getKey() instanceof String) ? (String) entry.getKey()
                    : ((MBeanOperationInfo) entry.getKey()).getName();
            operations.put(opName, (Function) entry.getValue());
        }

        Iterable<MBeanAttributeInfo> attrInfo = Iterables.transform(initialAttributes.entrySet(),
                new Function<Map.Entry<String, ?>, MBeanAttributeInfo>() {
                    @Override
                    public MBeanAttributeInfo apply(Map.Entry<String, ?> entry) {
                        return new MBeanAttributeInfo(entry.getKey(), entry.getValue().getClass().getName(),
                                entry.getKey(), true, false, false);
                    }
                });

        Iterable<MBeanOperationInfo> opInfo = Iterables.transform(initialOperations.keySet(),
                new Function<Object, MBeanOperationInfo>() {
                    public MBeanOperationInfo apply(Object it) {
                        if (it instanceof MBeanOperationInfo) {
                            return (MBeanOperationInfo) it;
                        } else if (it instanceof CharSequence) {
                            return new MBeanOperationInfo(it.toString(), "my descr", new MBeanParameterInfo[0],
                                    "void", MBeanOperationInfo.ACTION_INFO);
                        } else {
                            throw new IllegalArgumentException("Cannot convert " + it + " to MBeanOperationInfo");
                        }
                    }
                });

        mBeanInfo = new MBeanInfo(GeneralisedDynamicMBean.class.getName(), GeneralisedDynamicMBean.class.getName(),
                Iterables.toArray(attrInfo, MBeanAttributeInfo.class), new MBeanConstructorInfo[0],
                Iterables.toArray(opInfo, MBeanOperationInfo.class), new MBeanNotificationInfo[0]);
    }

    public void updateAttributeValue(String name, Object value) {
        attributes.put(name, value);
    }

    @Override
    public Object getAttribute(String s) {
        return attributes.get(s);
    }

    @Override
    public void setAttribute(Attribute attribute) {
        attributes.put(attribute.getName(), attribute.getValue());
    }

    @Override
    public AttributeList getAttributes(String[] strings) {
        AttributeList result = new AttributeList();
        for (Object obj : mBeanInfo.getAttributes()) {
            Attribute attrib = (Attribute) obj;
            result.add(new Attribute(attrib.getName(), attributes.get(attrib.getName())));
        }
        return result;
    }

    @Override
    public AttributeList setAttributes(AttributeList attributeList) {
        for (Object element : attributeList) {
            Attribute attrib = (Attribute) element;
            attributes.put(attrib.getName(), attrib.getValue());
        }
        return attributeList;
    }

    @Override
    public Object invoke(String s, Object[] objects, String[] strings) {
        Function op = operations.get(s);
        if (op != null) {
            return op.apply(objects);
        } else {
            throw new RuntimeException("Unknown operation " + s);
        }
    }

    @Override
    public MBeanInfo getMBeanInfo() {
        return mBeanInfo;
    }
}