All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.internal.net.management.model.TabularModel Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2022, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * https://oss.oracle.com/licenses/upl.
 */
package com.tangosol.internal.net.management.model;

import com.oracle.coherence.common.base.Exceptions;

import com.tangosol.net.management.OpenMBeanHelper;

import com.tangosol.net.management.annotation.MetricsLabels;
import com.tangosol.net.management.annotation.MetricsScope;
import com.tangosol.net.management.annotation.MetricsValue;

import com.tangosol.net.metrics.MBeanMetric;

import javax.management.Descriptor;
import javax.management.MBeanAttributeInfo;

import javax.management.modelmbean.DescriptorSupport;

import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;

import java.io.PrintStream;

import java.util.Arrays;

import java.util.function.BiFunction;
import java.util.function.Function;

/**
 * A base class for tabular attributes in an {@link AbstractModel MBean model}.
 *
 * @param  the type of the model representing rows in the table
 * @param  the type of the parent model
 *
 * @author Jonathan Knight 2022.09.10
 * @since 23.03
 */
public abstract class TabularModel
        implements ModelAttribute
    {
    // ----- constructors ---------------------------------------------------

    /**
     * Create a tabular model.
     * 

* The {@code sKeyName} attribute is the name of the attribute used to * uniquely identify a row in the table. The name must match one of the * attributes in the {@code aAttribute} array. * * @param sName the attribute name * @param sDescription the attribute description * @param sKeyName the name of the table row key attribute * @param aAttribute the attributes making up the table row * @param fnRowCount the function to obtain the row count from the parent model * @param fnRow the function to obtain a specific row model from the parent model */ protected TabularModel(String sName, String sDescription, String sKeyName, ModelAttribute[] aAttribute, Function fnRowCount, BiFunction fnRow) { int cAttribute = aAttribute.length; f_sName = sName; f_sDescription = sDescription; f_aAttribute = aAttribute; f_asAttributeNames = new String[cAttribute]; f_fnRowCount = fnRowCount; f_fnRow = fnRow; String[] asDescr = new String[cAttribute]; OpenType[] aoType = new OpenType[cAttribute]; boolean fHasMetrics = false; MBeanMetric.Scope scope = MBeanMetric.Scope.VENDOR; boolean fKeyFound = false; for (int i = 0; i < cAttribute; i++) { ModelAttribute attribute = aAttribute[i]; String sAttributeName = attribute.getName(); f_asAttributeNames[i] = sAttributeName; if (attribute.isMetric()) { fHasMetrics = true; scope = attribute.getMetricScope(); } asDescr[i] = sAttributeName; aoType[i] = attribute.getType(); fKeyFound = fKeyFound || sAttributeName.equals(sKeyName); } if (!fKeyFound) { throw new IllegalArgumentException("The key attribute \"" + sKeyName + "\" could not be found in the attributes array " + Arrays.toString(f_asAttributeNames)); } f_fHasMetrics = fHasMetrics; f_metricScope = scope; f_rowType = OpenMBeanHelper.createCompositeType(sKeyName, sDescription, f_asAttributeNames, asDescr, aoType); f_tableType = OpenMBeanHelper.createTabularType(sKeyName, sDescription, f_rowType, new String[] {sKeyName}); } // ----- ModelAttribute methods ----------------------------------------- @Override public String getName() { return f_sName; } @Override public String getDescription() { return f_sDescription; } @Override public Function getFunction() { return this::getTabularData; } @Override public TabularType getType() { return f_tableType; } @Override public MBeanAttributeInfo getMBeanAttributeInfo() { MBeanAttributeInfo info = m_attribute; if (info == null) { DescriptorSupport descriptor = new DescriptorSupport(); descriptor.setField(MetricsScope.KEY, f_metricScope.name()); if (f_fHasMetrics) { descriptor.setField(MetricsScope.KEY, MBeanMetric.Scope.VENDOR.name()); descriptor.setField(MetricsValue.DESCRIPTOR_KEY, f_sName); for (ModelAttribute attribute : f_aAttribute) { if (attribute.isMetric()) { String sName = attribute.getName(); Descriptor desc = attribute.getMBeanAttributeInfo().getDescriptor(); descriptor.setField(sName + '.' + MetricsScope.KEY, desc.getFieldValue(MetricsScope.KEY)); descriptor.setField(sName + '.' + MetricsValue.DESCRIPTOR_KEY, desc.getFieldValue(MetricsValue.DESCRIPTOR_KEY)); descriptor.setField(sName + '.' + MetricsLabels.DESCRIPTOR_KEY, desc.getFieldValue(MetricsLabels.DESCRIPTOR_KEY)); } } String[] asMetricNames = Arrays.stream(f_aAttribute) .filter(ModelAttribute::isMetric) .map(ModelAttribute::getName) .toArray(String[]::new); descriptor.setField("metrics.columns", asMetricNames); } info = m_attribute = new OpenMBeanAttributeInfoSupport(f_sName, f_sDescription, f_tableType, true, false, false, descriptor); } return info; } @Override public boolean isMetric() { return f_fHasMetrics; } @Override public MBeanMetric.Scope getMetricScope() { return f_metricScope; } // ----- TabularModel methods ------------------------------------------- /** * Returns a {@link TabularData table} of all the channel attributes for all channels. * * @return a {@link TabularData table} of all the channel attributes for all channels */ public TabularData getTabularData(M m) { try { TabularDataSupport table = new TabularDataSupport(f_tableType); int cRow = f_fnRowCount.apply(m); CompositeData[] rows = new CompositeData[cRow]; int cAttribute = f_aAttribute.length; for (int nRow = 0; nRow < cRow; nRow++) { Object[] aoValue = new Object[cAttribute]; for (int a = 0; a < cAttribute; a++) { R oRow = f_fnRow.apply(m, nRow); aoValue[a] = f_aAttribute[a].getFunction().apply(oRow); } rows[nRow] = new CompositeDataSupport(f_rowType, f_asAttributeNames, aoValue); } table.putAll(rows); return table; } catch (OpenDataException e) { throw Exceptions.ensureRuntimeException(e); } } /** * Return the row type. * * @return the row type */ public CompositeType getRowType() { return f_rowType; } /** * Return the attribute names. * * @return the attribute names */ public String[] getAttributeNames() { return f_asAttributeNames; } /** * Print the model's attributes to the specified {@link PrintStream}. * * @param out the {@link PrintStream} to print the attributes to * @param m the parent model * @param sPrefix the prefix to print at the start of the data */ public void dumpRows(PrintStream out, M m, String sPrefix) { int cRow = f_fnRowCount.apply(m); for (int nRow = 0; nRow < cRow; nRow++) { StringBuilder sb = new StringBuilder(sPrefix) .append(" row=") .append(nRow); for (ModelAttribute attribute : f_aAttribute) { R oRow = f_fnRow.apply(m, nRow); Object oValue = attribute.getFunction().apply(oRow); sb.append(", ").append(attribute.getName()).append("=").append(oValue); } out.println(sb); } } // ----- data members --------------------------------------------------- /** * That attribute name. */ private final String f_sName; /** * The attribute description. */ private final String f_sDescription; /** * The table row attributes. */ private final ModelAttribute[] f_aAttribute; /** * The attrbute names. */ private final String[] f_asAttributeNames; /** * The function to obtain the row count from the parent model. */ private final Function f_fnRowCount; /** * The function to obtain a row from the parent model */ private final BiFunction f_fnRow; /** * The data types in a row. */ private final TabularType f_tableType; /** * The composite row type. */ private final CompositeType f_rowType; /** * A flag indicating whether this table contains metrics attributes. */ private final boolean f_fHasMetrics; /** * The scope for any metrics in the table. */ private final MBeanMetric.Scope f_metricScope; /** * The lazily created {@link MBeanAttributeInfo} attribute definition. */ private volatile MBeanAttributeInfo m_attribute; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy