Skip navigation links

Package com.orchestranetworks.addon.dqid

Provides classes and interfaces to define, publish and execute indicators.

See: Description

Package com.orchestranetworks.addon.dqid Description

Provides classes and interfaces to define, publish and execute indicators.

Indicator creation - A basic example

To add a custom indicator, its definition must first be created. Since {addon.label} v1.5.2, you can declare an indicator definition and its execution in the same class by extending the DefaultDECIndicator or DefaultWorkflowIndicator class. For example:

        public final class TestDefaultDECIndicator extends DefaultDECIndicator
        {
                private static final String NUMBER_OF_RECORDS_PARAM = "numberOfRecords";
                private static final String LAST_MODIFICATION_TIME_PARAM = "lastModificationTime";
        
                public String getCode()
                {
                        return "TestDefaultDECIndicator"; // the code must be unique
                }
        
                public DECType getDECType()
                {
                        return DECType.TABLE;
                }
        
                public Set<FrequencyType> getPossibleComputationFrequencies()
                {
                        Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>();
                        frequencyTypes.add(FrequencyType.ON_DEMAND);
                        return frequencyTypes;
                }
        
                public List<ParameterDefinition> getOutputParametersDefinition()
                {
                        List<ParameterDefinition> outputs = new ArrayList<ParameterDefinition>();
        
                        UserMessageString nbOfRecordsMsg = UserMessage.createInfo("Number of records");
                        outputs.add(new ParameterDefinition(NUMBER_OF_RECORDS_PARAM, SchemaTypeName.XS_INT, nbOfRecordsMsg, nbOfRecordsMsg));
        
                        UserMessageString lastModificationTimeMsg = UserMessage.createInfo("Last modification time");
                        outputs.add(new ParameterDefinition(LAST_MODIFICATION_TIME_PARAM, SchemaTypeName.XS_DATETIME, lastModificationTimeMsg, lastModificationTimeMsg));
        
                        return outputs;
                }
                
                public BigDataDefinition getBigDataDefinition()
                {
                        BigDataDefinition bigDataDefinition = new BigDataDefinition();
                        bigDataDefinition.addPathAssociation(BigDataDefinition.NbRecordsTable, NUMBER_OF_RECORDS_PARAM);
                        bigDataDefinition.addPathAssociation(BigDataDefinition.LastUpdateDate, LAST_MODIFICATION_TIME_PARAM);
                        return bigDataDefinition;
                }
                
                // since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
                public FlatDataDefinition getFlatDataDefinition()
                {
                        FlatDataDefinition flatDataDefinition = new FlatDataDefinition();
                        flatDataDefinition.addPathAssociation(FlatDataDefinition.Integer1, NUMBER_OF_RECORDS_PARAM);
                        flatDataDefinition.addPathAssociation(FlatDataDefinition.Datetime1, LAST_MODIFICATION_TIME_PARAM);
                        return flatDataDefinition;
                }
        
                public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException
                {
                        IndicatorReport report = new IndicatorReport();
        
                        // sequence: 1, order: 1
                        Integer number = Integer.valueOf(100);
                        IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1); // built-in IndicatorValue
                        // deprecated since v2.0.0
                        // numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
                        numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number);
                        report.addValue(numberOfRecordsValue);
        
                        // sequence: 1, order: 2
                        Date date = new Date();
                        IndicatorValue modificationTimeValue = new IndicatorTestValue(date, 1, 2); // custom IndicatorValue
                        // deprecated since v2.0.0
                        // modificationTimeValue.setBigDataReportField(BigDataDefinition.LastUpdateDate, date);
                        modificationTimeValue.setFlatDataFieldValue(FlatDataDefinition.Datetime1, date);
                        report.addValue(modificationTimeValue);
        
                        return report;
                }
        
        }
        

Next, you can create a custom indicator value to store execution results if necessary. For example:

        public final class IndicatorTestValue extends IndicatorValue
        {
                private final Date date;

                public IndicatorTestValue(Date date, int sequence, int order)
                {
                        super(sequence, order);
                        this.date = date;
                }

                public String formatDataType()
                {
                        return Date.class.getSimpleName();
                }

                public String formatValue()
                {
                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        return df.format(this.date);
                }

                public Object getValue()
                {
                        return this.date;
                }
        }
        

Finally, the indicator must be registered with the add-on in order to be available in the configuration:

        IndicatorDefinitionCatalog.add(new TestDefaultDECIndicator());
        

 

By extending the default indicator classes, you can also apply multiple implementations on the same definition. For example, declare an abstract indicator definition as the following:

        public abstract class AbstractNumberOfRecordsIndicator extends DefaultDECIndicator
        {
                protected static final String NUMBER_OF_RECORDS_OUTPUT_PARAM = "numberOfRecords";
        
                public DECType getDECType()
                {
                        return DECType.TABLE;
                }
        
                public Set<FrequencyType> getPossibleComputationFrequencies()
                {
                        Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>();
                        frequencyTypes.add(FrequencyType.ON_DEMAND);
                        return frequencyTypes;
                }
        
                public List<ParameterDefinition> getOutputParametersDefinition()
                {
                        List<ParameterDefinition> outputs = new ArrayList<ParameterDefinition>();
                        UserMessageString nbOfRecordsMsg = UserMessage.createInfo("Number of records");
                        outputs.add(new ParameterDefinition(NUMBER_OF_RECORDS_OUTPUT_PARAM, SchemaTypeName.XS_INT, nbOfRecordsMsg, nbOfRecordsMsg));
                        return outputs;
                }
        
                public BigDataDefinition getBigDataDefinition()
                {
                        BigDataDefinition bigDataDefinition = new BigDataDefinition();
                        bigDataDefinition.addPathAssociation(BigDataDefinition.NbRecordsTable, NUMBER_OF_RECORDS_OUTPUT_PARAM);
                        return bigDataDefinition;
                }
                
                // since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
                public FlatDataDefinition getFlatDataDefinition()
                {
                        FlatDataDefinition flatDataDefinition = new FlatDataDefinition();
                        flatDataDefinition.addPathAssociation(FlatDataDefinition.Integer1, NUMBER_OF_RECORDS_OUTPUT_PARAM);
                        return flatDataDefinition;
                }
        
        }
        

Then extend the above class to handle the business in different scenarios:

        public final class NumberOfRecordsWithErrorsIndicator extends AbstractNumberOfRecordsIndicator
        {
        
                public String getCode()
                {
                        return "NumberOfRecordsWithErrors";
                }
        
                public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException
                {
                        IndicatorReport report = new IndicatorReport();
        
                        Integer number = Integer.valueOf(50);
                        IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1);
                        // deprecated since v2.0.0
                        // numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
                        numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number);
                        report.addValue(numberOfRecordsValue);
        
                        return report;
                }
        
        }
        
        public final class NumberOfRecordsWithWarningsIndicator extends AbstractNumberOfRecordsIndicator
        {
        
                public String getCode()
                {
                        return "NumberOfRecordsWithWarnings";
                }
        
                public IndicatorReport execute(DECIndicatorExecutionContext executionContext)
                        throws DQIdException
                {
                        IndicatorReport report = new IndicatorReport();
        
                        Integer number = Integer.valueOf(80);
                        IndicatorValue numberOfRecordsValue = new IntegerValue(number, 1, 1);
                        // deprecated since v2.0.0
                        // numberOfRecordsValue.setBigDataReportField(BigDataDefinition.NbRecordsTable, number);
                        numberOfRecordsValue.setFlatDataFieldValue(FlatDataDefinition.Integer1, number);
                        report.addValue(numberOfRecordsValue);
        
                        return report;
                }
        
        }
        

 

Indicator creation - A full-featured example

The following example covers in-depth all properties of an IndicatorDefinition instance:

        public final class IndicatorDurationDefinition implements IndicatorDefinition
        {
                private static final String TIME_PARAM = "TimeOutput";
                private static final String DURATION_PARAM = "DurationOutput";
        
                public IndicatorDurationDefinition()
                {
        
                }
        
                public String getCode()
                {
                        return "Indicator-Duration";
                }
        
                public UserMessage getLabel()
                {
                        return UserMessage.createInfo("Time duration in interval format");
                }
        
                public UserMessage getDashboardLabel()
                {
                        return UserMessage.createInfo("Time duration");
                }
        
                public UserMessage getDescription()
                {
                        return UserMessage.createInfo("This indicator checks if the value of a Datetime field is within a specified time range "
                                + "and displays the time range from that time to the execution time in interval format.");
                }
        
                public Indicator getImplementation()
                {
                        return new IndicatorDurationImpl(); // this implementation class is defined below
                }
        
                public DECType getDECType()
                {
                        return DECType.FIELD;
                }
        
                public DECSubType getDECSubType()
                {
                        // return null if the indicator doesn't have any D.E.C. sub-types
                        return FieldDECSubType.DATE; // this indicator can only be configured and executed on fields with the Date type
                }
        
                public List<ParameterDefinition> getInputParametersDefinition()
                {
                        // return null if the indicator doesn't have any input parameters
                        List<ParameterDefinition> inputs = new ArrayList<ParameterDefinition>();
        
                        // numeric input
                        UserMessage maxNbOfOutcomesLabel = UserMessage.createInfo("Maximum number of outcomes");
                        UserMessage maxNbOfOutcomesDescription = UserMessage.createInfo("The maximum of outcomes (also the Big data records) for an execution.");
                        ParameterDefinition maxNumberOfOutputs = new ParameterDefinition(
                                "maxNumberOfOutcomesInput",
                                SchemaTypeName.XS_INTEGER,
                                maxNbOfOutcomesLabel,
                                maxNbOfOutcomesDescription,
                                String.valueOf(1));
                        // optional constraint for an input parameter
                        ParameterConstraint parameterConstraint = new ParameterConstraint();
                        parameterConstraint.setUnboundedSupported(true);
                        maxNumberOfOutputs.setParameterConstraint(parameterConstraint);
                        inputs.add(maxNumberOfOutputs);
        
                        // datetime inputs
                        UserMessage fromTimeLabel = UserMessage.createInfo("From");
                        UserMessage fromTimeDescription = UserMessage.createInfo("The start time of the time range. Only considered if the configured periodicity is 'None'.");
                        ParameterDefinition fromDate = new ParameterDefinition(
                                "fromTimeInput",
                                SchemaTypeName.XS_DATETIME,
                                fromTimeLabel,
                                fromTimeDescription);
                        inputs.add(fromDate);
        
                        UserMessage toDateLabel = UserMessage.createInfo("To");
                        UserMessage toDateDescription = UserMessage.createInfo("The end time of the time range. Only considered if the configured periodicity is 'None'.");
                        ParameterDefinition toDate = new ParameterDefinition(
                                "toTimeInput",
                                SchemaTypeName.XS_DATETIME,
                                toDateLabel,
                                toDateDescription);
                        inputs.add(toDate);
        
                        // enumeration input with interval formats
                        UserMessage intervalFormatLabel = UserMessage.createInfo("Interval format");
                        UserMessage intervalFormatDescription = UserMessage.createInfo("The interval format for the 'Duration' output.");
        
                        Set<PredefinedValue> formats = new HashSet<PredefinedValue>();
                        formats.add(new PredefinedValue(IntervalType.DAY_HOUR.getCode(), IntervalType.DAY_HOUR.getLabel()));
                        formats.add(new PredefinedValue(IntervalType.DAY_HOUR_MINUTE.getCode(), IntervalType.DAY_HOUR_MINUTE.getLabel()));
        
                        PredefinedValue defaultFormat = new PredefinedValue(IntervalType.DAY_HOUR.getCode()); // default selected option of the list
                        ListConstraint listConstraint = new ListConstraint(formats, Collections.singleton(defaultFormat));
        
                        ParameterDefinition intervalFormat = new ParameterDefinition(
                                "intervalFormatInput",
                                SchemaTypeName.XS_STRING,
                                intervalFormatLabel,
                                intervalFormatDescription,
                                listConstraint,
                                HTMLComponent.DROPDOWNBOX_COMPONENT); // HTML type for the input
                        inputs.add(intervalFormat);
        
                        return Collections.unmodifiableList(inputs);
                }
        
                public List<ParameterDefinition> getOutputParametersDefinition()
                {
                        List<ParameterDefinition> parameterDefinitions = new ArrayList<ParameterDefinition>();
        
                        UserMessage timeLabel = UserMessage.createInfo("Time in range");
                        UserMessage timeDescription = UserMessage.createInfo("Displays the datetime value within the time range.");
                        ParameterDefinition timeOutput = new ParameterDefinition(
                                IndicatorDurationDefinition.TIME_PARAM,
                                SchemaTypeName.XS_DATETIME,
                                timeLabel,
                                timeDescription);
                        parameterDefinitions.add(timeOutput);
        
                        UserMessage durationLabel = UserMessage.createInfo("Time duration in interval");
                        UserMessage durationDescription = UserMessage.createInfo("Displays the time range from a certain time to the execution time in interval format.");
                        ParameterDefinition durationOutput = new ParameterDefinition(
                                IndicatorDurationDefinition.DURATION_PARAM,
                                SchemaTypeNameExtension.INTERVAL,
                                durationLabel,
                                durationDescription);
                        parameterDefinitions.add(durationOutput);
        
                        return parameterDefinitions;
                }
        
                public BigDataDefinition getBigDataDefinition()
                {
                        BigDataDefinition bigDataDefinition = new BigDataDefinition();
                        bigDataDefinition.addPathAssociation(BigDataDefinition.OverseeDateValue, IndicatorDurationDefinition.TIME_PARAM);
                        bigDataDefinition.addPathAssociation(BigDataDefinition.LifeTimeOfDataspace, IndicatorDurationDefinition.DURATION_PARAM);
                        return bigDataDefinition;
                }
                
                // since v2.0.0, it is recommended to declare FlatDataDefinition instead of BigDataDefinition
                public FlatDataDefinition getFlatDataDefinition()
                {
                        FlatDataDefinition flatDataDefinition = new FlatDataDefinition();
                        flatDataDefinition.addPathAssociation(FlatDataDefinition.Datetime1, IndicatorDurationDefinition.TIME_PARAM);
                        flatDataDefinition.addPathAssociation(FlatDataDefinition.Interval1, IndicatorDurationDefinition.DURATION_PARAM);
                        return flatDataDefinition;
                }
        
                public Set<FrequencyType> getPossibleComputationFrequencies()
                {
                        // supports both the on-demand and the real-time computations
                        Set<FrequencyType> frequencyTypes = new HashSet<FrequencyType>();
                        frequencyTypes.add(FrequencyType.ON_DEMAND);
                        frequencyTypes.add(FrequencyType.REAL_TIME);
                        return frequencyTypes;
                }
        
                public Set<ProbeType> getPossibleProbes()
                {
                        // returns null if the indicator runs on-demand
                        return Collections.singleton(ProbeType.TRIGGER); // supports probes for a real-time indicator
                }
        
                public WatchdogInformation getWatchdogInformation()
                {
                        // return null if the indicator doesn't have any periodicities or thresholds
                        WatchdogInformation information = new WatchdogInformation();
                        Set<PeriodicityType> possiblePeriodicities = new HashSet<PeriodicityType>();
                        possiblePeriodicities.add(PeriodicityType.DAILY);
                        possiblePeriodicities.add(PeriodicityType.TOLERANCE); // TOLERANCE or 'None' means using the configured time range
                        information.setPossiblePeriodicityOfControl(Collections.unmodifiableSet(possiblePeriodicities));
                        return information;
                }
        
                public UserMessage getStorageProcedureInformation()
                {
                        return UserMessage.createInfo("Any results are stored.");
                }
        
                // deprecated since v2.0.0
                public boolean hasManyOutcomesStoredInBigDataTable()
                {
                        return true; // has multiple outcomes because there may be many datetime values within a time ranges
                }

                public boolean hasManyOutcomesStoredInReportingTable()
                {
                        return true; // has multiple outcomes because there may be many datetime values within a time ranges
                }
        
                public LinkedRecordDefinition getLinkedRecordDefinition()
                {
                        // return null if the indicator doesn't store any records
                        LinkedRecordDefinition linkedRecordDefinition = new LinkedRecordDefinition(UserMessage.createInfo("Records with time duration greater than one day will be stored"));
                        UserMessage label = UserMessage.createInfo("Duration greater than one day.");
                        UserMessage description = UserMessage.createInfo("Records with time duration greater than one day will be stored.");
                        linkedRecordDefinition.addOption(new ParameterDefinition(
                                "DurationLinkedRecordOption",
                                SchemaTypeName.XS_BOOLEAN,
                                label,
                                description,
                                Boolean.TRUE.toString()));
                        return linkedRecordDefinition;
                }
        }
        

Next, the definition of the indicator value to be stored must be created. For example:

        public final class IndicatorTestValue extends IndicatorValue
        {
                private final Date date;

                public IndicatorTestValue(Date date, int sequence, int order)
                {
                        super(sequence, order);
                        this.date = date;
                }

                public String formatDataType()
                {
                        return Date.class.getSimpleName();
                }

                public String formatValue()
                {
                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        return df.format(this.date);
                }

                public Object getValue()
                {
                        return this.date;
                }
        }
        

To execute the indicator, the definition of the implementation must first be created. The following example illustrates how to get and handle indicator configuration properties:

        public class IndicatorDurationImpl extends DECIndicator
        {
                private static final int TIME_OF_A_DAY = 1000 * 60 * 60 * 24;
        
                public IndicatorReport execute(DECIndicatorExecutionContext executionContext) throws DQIdException
                {
                        IndicatorDefinitionContext definitionContext = this.getIndicatorDefinitionContext();
        
                        // input parameter values
                        String maxNbOfOutcomeValue = definitionContext.getBespokeParameterValue("maxNumberOfOutcomesInput");
                        String fromTimeValue = definitionContext.getBespokeParameterValue("fromTimeInput");
                        String toTimeValue = definitionContext.getBespokeParameterValue("toTimeInput");
                        String intervalFormatValue = definitionContext.getBespokeParameterValue("intervalFormatInput");
                        String linkedRecordOption = definitionContext.getLinkedRecordInformation().getOption("DurationLinkedRecordOption");
        
                        int maxNbOfOutcomes;
                        try
                        {
                                maxNbOfOutcomes = Integer.parseInt(maxNbOfOutcomeValue);
                        }
                        catch (NumberFormatException ex)
                        {
                                throw new DQIdException(UserMessage.createError("Invalid maximum number of outcomes."));
                        }
        
                        // periodicity
                        Watchdog watchdog = definitionContext.getWatchdog();
                        PeriodicityType periodicityType = watchdog == null ? null : watchdog.getPeriodicityOfControl();
        
                        Date fromTime = null;
                        Date toTime = null;
                        // if the periodicity is 'None'
                        if (periodicityType.isTolerance())
                        {
                                if (fromTimeValue == null || toTimeValue == null)
                                {
                                        throw new DQIdException(UserMessage.createError("Invalid time."));
                                }
                                fromTime = FormatDataPolicy.parseDate(SchemaTypeName.XS_DATETIME, fromTimeValue);
                                toTime = FormatDataPolicy.parseDate(SchemaTypeName.XS_DATETIME, toTimeValue);
                        }
                        else
                        {
                                // other cases to check if a date value is within the periodicity
                        }
                        if (fromTime == null || toTime == null)
                        {
                                throw new DQIdException(UserMessage.createError("Invalid time."));
                        }
                        if (toTime.before(fromTime))
                        {
                                throw new DQIdException(UserMessage.createError("From time cannot be before to time."));
                        }
        
                        AdaptationTable table = executionContext.getExecutionEnvironment().getTable();
                        Path fieldPath = definitionContext.getField();
                        Date executionTime = new Date();
                        IntervalType intervalType = IntervalType.DAY_HOUR_MINUTE.getCode().equals(intervalFormatValue) ? IntervalType.DAY_HOUR_MINUTE : IntervalType.DAY_HOUR;
                        boolean saveLastValueOnlyInReporting = definitionContext.saveLastValueOnlyInFlatDataTable();
                        boolean storeAll = !Boolean.getBoolean(linkedRecordOption);
        
                        IndicatorReport indicatorReport;
                        if (executionContext.isOnDemand()) // on-demand execution
                        {
                                indicatorReport = this.executeOnDemand(
                                        executionContext,
                                        table,
                                        fieldPath,
                                        fromTime,
                                        toTime,
                                        executionTime,
                                        intervalType,
                                        maxNbOfOutcomes,
                                        saveLastValueOnlyInReporting,
                                        storeAll);
                        }
                        else // real-time execution
                        {
                                String currentRecordXPath = executionContext.getCurrentRecordXPathPredicate();
                                indicatorReport = this.executeRealtime(
                                        executionContext,
                                        table,
                                        fieldPath,
                                        currentRecordXPath,
                                        fromTime,
                                        toTime,
                                        executionTime,
                                        intervalType,
                                        maxNbOfOutcomes,
                                        saveLastValueOnlyInReporting,
                                        storeAll);
                        }
                        if (indicatorReport == null)
                        {
                                return null;
                        }
        
                        // indicates that the watchdog is used as an alert to save the indicator report
                        indicatorReport.setAlertRaisedByWatchdog(true);
                        return indicatorReport;
                }
        
                private IndicatorReport executeOnDemand(
                        DECIndicatorExecutionContext executionContext,
                        AdaptationTable table,
                        Path fieldPath,
                        Date fromTime,
                        Date toTime,
                        Date executionTime,
                        IntervalType intervalType,
                        int maxNbOfOutcomes,
                        boolean saveLastValueOnlyInReporting,
                        boolean storeAll) throws DQIdException
                {
                        IndicatorReport indicatorReport = new IndicatorReport();
                        int sequence = 1; // sequence always starts with 1
                        RequestResult requestResult = table.createRequest().execute();
                        try
                        {
                                Adaptation record = null;
                                while ((record = requestResult.nextAdaptation()) != null)
                                {
                                        Date datetime = record.getDate(fieldPath);
                                        if (datetime.before(fromTime) || datetime.after(toTime) || datetime.after(executionTime))
                                        {
                                                continue;
                                        }
                                        if (sequence > maxNbOfOutcomes)
                                        {
                                                break;
                                        }
                                        this.addIndicatorValues(
                                                executionContext,
                                                indicatorReport,
                                                datetime,
                                                executionTime,
                                                intervalType,
                                                sequence,
                                                saveLastValueOnlyInReporting,
                                                record.toXPathPredicateString(),
                                                storeAll);
                                        sequence++;
                                }
                        }
                        finally
                        {
                                requestResult.close();
                        }
                        return indicatorReport;
                }
        
                private IndicatorReport executeRealtime(
                        DECIndicatorExecutionContext executionContext,
                        AdaptationTable table,
                        Path fieldPath,
                        String currentRecordXPath,
                        Date fromTime,
                        Date toTime,
                        Date executionTime,
                        IntervalType intervalType,
                        int maxNbOfOutcomes,
                        boolean saveLastValueOnlyInReporting,
                        boolean storeAll) throws DQIdException
                {
                        if (maxNbOfOutcomes <= 0 || AddonStringUtils.isEmpty(currentRecordXPath))
                        {
                                return null;
                        }
                        RequestResult requestResult = table.createRequestResult(currentRecordXPath);
                        try
                        {
                                Adaptation record = requestResult.nextAdaptation();
                                if (record == null)
                                {
                                        return null;
                                }
                                Date datetime = record.getDate(fieldPath);
                                if (datetime.before(fromTime) || datetime.after(toTime) || datetime.after(executionTime))
                                {
                                        return null;
                                }
                                IndicatorReport indicatorReport = new IndicatorReport();
                                this.addIndicatorValues(
                                        executionContext,
                                        indicatorReport,
                                        datetime,
                                        executionTime,
                                        intervalType,
                                        1,
                                        saveLastValueOnlyInReporting,
                                        record.toXPathPredicateString(),
                                        storeAll);
                                return indicatorReport;
                        }
                        finally
                        {
                                requestResult.close();
                        }
                }
        
                private void addIndicatorValues(
                        DECIndicatorExecutionContext executionContext,
                        IndicatorReport indicatorReport,
                        Date datetime,
                        Date executionTime,
                        IntervalType intervalType,
                        int sequence,
                        boolean saveLastValueOnlyInReporting,
                        String recordPredicate,
                        boolean storeAll) throws DQIdException
                {
                        // indicator values
                        IndicatorValue datetimeValue = new IndicatorTestValue(datetime, sequence, 1); // IndicatorTestValue was defined before
                        // deprecated since v2.0.0
                        // datetimeValue.setBigDataReportField(BigDataDefinition.OverseeDateValue, datetimeValue);
                        datetimeValue.setFlatDataFieldValue(FlatDataDefinition.Datetime1, datetimeValue);
                        indicatorReport.addValue(datetimeValue);
        
                        long duration = executionTime.getTime() - datetime.getTime();
                        // IntervalValue is an available implementation class of IndicatorValue
                        IndicatorValue intervalValue = new IntervalValue(BigDecimal.valueOf(duration), sequence, 2, intervalType);
                        // deprecated since v2.0.0
                        // datetimeValue.setBigDataReportField(BigDataDefinition.LifeTimeOfDataspace, BigDecimal.valueOf(duration));
                        datetimeValue.setFlatDataFieldValue(FlatDataDefinition.Interval1, BigDecimal.valueOf(duration));
                        indicatorReport.addValue(intervalValue);
        
                        // handle saving last value in the Flat data table
                        if (saveLastValueOnlyInReporting)
                        {
                                // deprecated since v2.0.0
                                // indicatorReport.setPrimaryKeyOfPreviousBigDataReportBySequence(sequence, this.getPrimaryKeyOrNullOfExistingIndicatorReportInBigDataTable(executionContext, sequence));
                                indicatorReport.setPrimaryKeyOfPreviousReportingRecordBySequence(sequence, this.getFlatDataAccessor().getPrimaryKeyOrNullOfLatestRecord(executionContext, sequence));           
                        }
        
                        // linked record - check if duration is greater than a day 
                        if (!storeAll && duration <= TIME_OF_A_DAY)
                        {
                                return;
                        }
                        LinkedRecord linkedRecord = new LinkedRecord();
                        linkedRecord.addRelevantRecordPredicate(recordPredicate);
                        indicatorReport.addLinkedRecord(sequence, linkedRecord);
                }
        }
        

Finally, the indicator must be registered with the add-on in order to be available in the configuration:

        IndicatorDefinitionCatalog.add(new IndicatorDurationDefinition());
        
Skip navigation links

Add-ons Version 4.5.22.

Copyright 2001-2025. Cloud Software Group, Inc. All rights reserved.
All third party product and company names and third party marks mentioned in this document are the property of their respective owners and are mentioned for identification.