/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) ESO - European Southern Observatory, 2011 * (in the framework of the ALMA collaboration). * All rights reserved. * * This library 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 library 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 library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *******************************************************************************/ package alma.acs.monitoring.blobber; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.omg.CORBA.Any; import org.omg.CORBA.TypeCodePackage.BadKind; import alma.ACSErrTypeCommon.wrappers.AcsJNoResourcesEx; import alma.TMCDB.booleanBlobData; import alma.TMCDB.booleanBlobDataSeqHelper; import alma.TMCDB.booleanSeqBlobData; import alma.TMCDB.booleanSeqBlobDataSeqHelper; import alma.TMCDB.doubleBlobData; import alma.TMCDB.doubleBlobDataSeqHelper; import alma.TMCDB.doubleSeqBlobData; import alma.TMCDB.doubleSeqBlobDataSeqHelper; import alma.TMCDB.enumBlobData; import alma.TMCDB.enumBlobDataSeqHelper; import alma.TMCDB.floatBlobData; import alma.TMCDB.floatBlobDataSeqHelper; import alma.TMCDB.floatSeqBlobData; import alma.TMCDB.floatSeqBlobDataSeqHelper; import alma.TMCDB.longBlobData; import alma.TMCDB.longBlobDataSeqHelper; import alma.TMCDB.longLongBlobData; import alma.TMCDB.longLongBlobDataSeqHelper; import alma.TMCDB.longLongSeqBlobData; import alma.TMCDB.longLongSeqBlobDataSeqHelper; import alma.TMCDB.longSeqBlobData; import alma.TMCDB.longSeqBlobDataSeqHelper; import alma.TMCDB.patternBlobData; import alma.TMCDB.patternBlobDataSeqHelper; import alma.TMCDB.stringBlobData; import alma.TMCDB.stringBlobDataSeqHelper; import alma.TMCDB.stringSeqBlobData; import alma.TMCDB.stringSeqBlobDataSeqHelper; import alma.TMCDB.uLongBlobData; import alma.TMCDB.uLongBlobDataSeqHelper; import alma.TMCDB.uLongLongBlobData; import alma.TMCDB.uLongLongBlobDataSeqHelper; import alma.TMCDB.uLongLongSeqBlobData; import alma.TMCDB.uLongLongSeqBlobDataSeqHelper; import alma.TMCDB.uLongSeqBlobData; import alma.TMCDB.uLongSeqBlobDataSeqHelper; import alma.acs.monitoring.MonitorPointTimeSeries; import alma.acs.monitoring.MonitorPointValue; /** * Processes the monitor point data that arrives to the blobber in the form of Corba Anys. * <p> * TODOs: * <ul> * <li>Refactor this class to separate the two steps of * (a) unpacking corba any data, * (b) demultiplexing sequence data using MonitorPointExpert. * Note that with ACS 12.2 we already removed the generation of CLOB data which was also mixed in to this code. * <li>Long-term: IDL struct MonitorBlob should perhaps be defined without using Corba Any (performance!). * Rather use separate fields for the possible data types. * <ul> */ class AnyExtractor { private final Logger logger; private final MonitorPointExpert monitorPointExpert; /** * @param logger * @param monitorPointExpert TODO remove this once the extractor only extracts corba anys w/o other processing */ AnyExtractor(Logger logger, MonitorPointExpert monitorPointExpert) { this.logger = logger; this.monitorPointExpert = monitorPointExpert; } /** * The main method of this class. * It checks <code>inSequence</code> for the recognized data types * and extracts them using the respective Corba Helper classes. * We keep NaN floating point types, so that they will have to be supressed later in the * data processing if needed. * <p> * Currently this method also rearranges the sequence data based on information * obtained from monitorPointExpert. This should be done separately in the future. * * @param inSequence * The sequence of data from one property (monitor point) from one collector interval. * @param propertyName Used along with {@link #monitorPointExpert} for MP-specific data restructuring. * @return List of one or many MonitorPointTimeSeries objects extracted from inSequence. * The list position is in line with the "derived index" in case a monitor point was expanded into many. * @throws AcsJNoResourcesEx */ List<MonitorPointTimeSeries> extractData(Any inSequence, String propertyName) throws AcsJNoResourcesEx { List<MonitorPointTimeSeries> outList = new ArrayList<MonitorPointTimeSeries>(); try { // doubleBlobDataSeq // This is time series data coming from a simple property. // For this case, the index, i.e., the position inside the sequence is 0 if (inSequence.type().equal(doubleBlobDataSeqHelper.type())) { doubleBlobData[] blobDataArray = doubleBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, doubleBlobDataSeqHelper.type().id()); outList.add(mpTs); for (doubleBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Double mpTs.addMonitorPointValue(mpv); } } // doubleSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(doubleSeqBlobDataSeqHelper.type())) { doubleSeqBlobData[] blobDataMatrix = doubleSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, doubleSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (doubleSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (double value : blobDataArray.value) { mpv.addValue(value); // Double } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, doubleBlobDataSeqHelper.type().id()); for (doubleSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (double value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Double MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // floatBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(floatBlobDataSeqHelper.type())) { floatBlobData[] blobDataArray = floatBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, floatBlobDataSeqHelper.type().id()); outList.add(mpTs); for (floatBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Float mpTs.addMonitorPointValue(mpv); } } // floatSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(floatSeqBlobDataSeqHelper.type())) { floatSeqBlobData[] blobDataMatrix = floatSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, floatSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (floatSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (float value : blobDataArray.value) { mpv.addValue(value); // Float } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, floatBlobDataSeqHelper.type().id()); for (floatSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (float value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Float MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // longBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(longBlobDataSeqHelper.type())) { longBlobData[] blobDataArray = longBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, longBlobDataSeqHelper.type().id()); outList.add(mpTs); for (longBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Long mpTs.addMonitorPointValue(mpv); } } // longSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(longSeqBlobDataSeqHelper.type())) { longSeqBlobData[] blobDataMatrix = longSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, longSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (longSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (long value : blobDataArray.value) { mpv.addValue(value); // Long } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, longBlobDataSeqHelper.type().id()); for (longSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (long value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Long MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // uLongBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(uLongBlobDataSeqHelper.type())) { uLongBlobData[] blobDataArray = uLongBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, uLongBlobDataSeqHelper.type().id()); outList.add(mpTs); for (uLongBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); // TODO: use Long and fix mismatch if blobData.value < 0 mpv.addValue(blobData.value); // Integer mpTs.addMonitorPointValue(mpv); } } // uLongSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(uLongSeqBlobDataSeqHelper.type())) { uLongSeqBlobData[] blobDataMatrix = uLongSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, uLongSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (uLongSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (int value : blobDataArray.value) { // TODO: use Long and fix mismatch if value < 0 mpv.addValue(value); // Integer } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, uLongBlobDataSeqHelper.type().id()); for (uLongSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (int value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); // TODO: use Long and fix mismatch if value < 0 mpv.addValue(value); // Integer MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // longLongBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(longLongBlobDataSeqHelper.type())) { longLongBlobData[] blobDataArray = longLongBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, longLongBlobDataSeqHelper.type().id()); outList.add(mpTs); for (longLongBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Long mpTs.addMonitorPointValue(mpv); } } // longLongSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(longLongSeqBlobDataSeqHelper.type())) { longLongSeqBlobData[] blobDataMatrix = longLongSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, longLongSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (longLongSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (long value : blobDataArray.value) { mpv.addValue(value); // Long } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, longLongBlobDataSeqHelper.type().id()); for (longLongSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (long value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Long MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // uLongLongBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(uLongLongBlobDataSeqHelper.type())) { uLongLongBlobData[] blobDataArray = uLongLongBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, uLongLongBlobDataSeqHelper.type().id()); outList.add(mpTs); for (uLongLongBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); // TODO: Use BigInteger and fix mismatch for negative values, something like // if (blobData.value < 0) {BigInteger.valueOf(blobData.value).add(new BigInteger("10000000000000000", 16))); // This will not resolve overflow problems with computing the statistics though. // Or better get rid of "unsigned long long" in our IDL, or replace it with something like // "typedef fixed<31,0> BigInt" mpv.addValue(blobData.value); // Long mpTs.addMonitorPointValue(mpv); } } // uLongLongSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(uLongLongSeqBlobDataSeqHelper.type())) { uLongLongSeqBlobData[] blobDataMatrix = uLongLongSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, uLongLongSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (uLongLongSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); // TODO: See type mismatch comment above for uLongLongBlobDataSeq for (long value : blobDataArray.value) { mpv.addValue(value); // Long } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, uLongLongBlobDataSeqHelper.type().id()); for (uLongLongSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; // TODO: See type mismatch comment above for uLongLongBlobDataSeq for (long value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Long MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // booleanBlobDataSeq // This is time series data coming from a simple property. else if (inSequence.type().equal(booleanBlobDataSeqHelper.type())) { booleanBlobData[] blobDataArray = booleanBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, booleanBlobDataSeqHelper.type().id()); outList.add(mpTs); for (booleanBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Boolean mpTs.addMonitorPointValue(mpv); } } // booleanSeqBlobDataSeq // This is time series data coming from a multi-valued property. else if (inSequence.type().equal(booleanSeqBlobDataSeqHelper.type())) { booleanSeqBlobData[] blobDataMatrix = booleanSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, booleanSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (booleanSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (boolean value : blobDataArray.value) { mpv.addValue(value); // Boolean } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, booleanBlobDataSeqHelper.type().id()); for (booleanSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (boolean value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // Boolean MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // patternBlobDataSeq else if (inSequence.type().equal(patternBlobDataSeqHelper.type())) { patternBlobData[] blobDataArray = patternBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, patternBlobDataSeqHelper.type().id()); outList.add(mpTs); for (patternBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Long mpTs.addMonitorPointValue(mpv); } } // stringBlobDataSeq else if (inSequence.type().equal(stringBlobDataSeqHelper.type())) { stringBlobData[] blobDataArray = stringBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, stringBlobDataSeqHelper.type().id()); outList.add(mpTs); for (stringBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // String mpTs.addMonitorPointValue(mpv); } } // stringSeqBlobDataSeq else if (inSequence.type().equal(stringSeqBlobDataSeqHelper.type())) { stringSeqBlobData[] blobDataMatrix = stringSeqBlobDataSeqHelper.extract(inSequence); if (blobDataMatrix != null && blobDataMatrix.length > 0) { if (monitorPointExpert.isMultivaluedMonitorPoint(propertyName)) { // We interpret this as a time series of a single multi-valued monitor point MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, stringSeqBlobDataSeqHelper.type().id()); outList.add(mpTs); for (stringSeqBlobData blobDataArray : blobDataMatrix) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); for (String value : blobDataArray.value) { mpv.addValue(value); // String } mpTs.addMonitorPointValue(mpv); } } else { // We interpret this as a time series of multiple single-valued monitor points populateList(outList, blobDataMatrix[0].value.length, stringBlobDataSeqHelper.type().id()); for (stringSeqBlobData blobDataArray : blobDataMatrix) { int index = 0; for (String value : blobDataArray.value) { MonitorPointValue mpv = new MonitorPointValue(blobDataArray.time); mpv.addValue(value); // String MonitorPointTimeSeries mpTs = outList.get(index); mpTs.addMonitorPointValue(mpv); index++; } } } } } // enumBlobDataSeq else if (inSequence.type().equal(enumBlobDataSeqHelper.type())) { enumBlobData[] blobDataArray = enumBlobDataSeqHelper.extract(inSequence); MonitorPointTimeSeries mpTs = new MonitorPointTimeSeries(0, enumBlobDataSeqHelper.type().id()); outList.add(mpTs); for (enumBlobData blobData : blobDataArray) { MonitorPointValue mpv = new MonitorPointValue(blobData.time); mpv.addValue(blobData.value); // Integer mpTs.addMonitorPointValue(mpv); } } else { logger.warning("Unknown CORBA data type received by blobber"); throw new IllegalStateException("Unknown CORBA data type received, " + inSequence.type()); } } catch (BadKind ex) { // This should never happen because we call TypeCode.id() only on TypeCodes // that do have an ID. logger.log(Level.WARNING, "Unexpected exception related to reading Any TypeCode IDs.", ex); } return outList; } /** * Populate inList with the inCount number of containers. */ private void populateList(List<MonitorPointTimeSeries> inList, int inCount, String anyTypeCode) { for (int index = 0; index < inCount; index++) { inList.add(new MonitorPointTimeSeries(index, anyTypeCode)); } } }