def getTargetCycleTime(self, context):
        """Return cycletime of basis datasources."""
        datasources_by_varname = {}
        for template in context.getRRDTemplates():
            for datasource in template.datasources():
                for datapoint in datasource.datapoints():
                    datasources_by_varname[datapoint.id] = datasource
                    datasources_by_varname[datapoint.name()] = datasource

        cycletimes = set()

        for varname in getVarNames(self.expression):
            datasource = datasources_by_varname.get(varname)
            if not datasource:
                continue

            # Some types of datasources such as PythonDataSource and
            # UCSDataSource implement a getCycleTime(context) method that
            # provides a context-specific interval instead of the static
            # cycletime property used by most other types of datasources. We
            # want to prefer the getCycleTime method's result to the cycletime
            # value because it will actually be the real collection interval
            # of the basis datasource.
            if datasource.aqBaseHasAttr("getCycleTime"):
                cycletimes.add(int(datasource.getCycleTime(context)))
            elif datasource.aqBaseHasAttr("cycletime"):
                cycletimes.add(int(datasource.cycletime))

        if cycletimes:
            # It's common for multiple basis datapoints to be used in the
            # expression. In cases where different datapoints in the
            # expression have different intervals, we'll choose the shortest
            # interval.
            return min(cycletimes)
    def params(cls, datasource, context):
        targetInfos = []
        # add an id->contents map for each component/device
        for member in dotTraverse(context, datasource.targetMethod or '') or []:
            targetInfos.append(targetInfo(member))

        targetArgValues = []
        for datapoint in datasource.datapoints():
            if isinstance(datapoint, AggregatingDataPoint):
                for att in getVarNames(datapoint.arguments.strip()):
                    targetArgValues.append(dotTraverse(context, att))
            else:
                log.error("datasource %s has a datapoint of the wrong type %s" % (datasource, datapoint))

            # should be only datapoint, so ...
            break

        zDebug = context.getZ('zDatasourceDebugLogging')
        return dict(
            targetDatapoints = [(datasource.targetDataSource, datasource.targetDataPoint,
                                 datasource.targetRRA or 'AVERAGE')],
            targetArgValues=[tuple(targetArgValues)],
            targets=targetInfos,
            debug=datasource.debug or zDebug
        )
def handleArguments(targetArgValues, dpargs):
    tokens = dpargs.strip().split(',') if dpargs.strip() else []
    arguments = []
    for tok, x in izip(tokens, range(len(tokens))):
        arguments.append(
            targetArgValues[x] if getVarNames(tok) else tok.strip())

    return arguments
    def params(cls, datasource, context):
        zDebug = context.getZ('zDatasourceDebugLogging')
        config = {
            'targets': [targetInfo(context)],
            'expression': datasource.expression,
            'debug': datasource.debug or zDebug,
            'template': datasource.rrdTemplate().getPrimaryId()
        }

        attrs = {}
        targetDataPoints = []

        allDatapointsByVarName = {}
        for dp in context.getRRDDataPoints():
            allDatapointsByVarName[dp.id] = dp
            allDatapointsByVarName[dp.name()] = dp

        for att in getVarNames(datasource.expression):

            if att in allDatapointsByVarName:
                datapoint = allDatapointsByVarName[att]
                targetDataPoints.append((datapoint.datasource().id, datapoint.id, 'AVERAGE'))
            else:
                value = dotTraverse(context, att)
                if not CalculatedDataSourcePlugin.isPicklable(value):
                    log.error("Calculated Performance expression %s references "
                        "invalid attribute (unpicklable value) %s" %(datasource.expression, att))
                    return config
                attrs[att] = value
                if value is None:
                    log.warn(
                        "Calculated Performance expression %s references "
                        "the variable %s which is not in %s" % (
                            datasource.expression, att, allDatapointsByVarName.keys()))

        config['obj_attrs'] = attrs
        config['targetDatapoints'] = targetDataPoints
        return config
    def params(cls, datasource, context):
        zDebug = context.getZ('zDatasourceDebugLogging')
        config = {
            'expression': datasource.expression,
            'debug': datasource.debug or zDebug,
            'template': datasource.rrdTemplate().getPrimaryId()}

        attrs = {}
        targetDatapoints = {}

        # Keep track of all datapoints from all targets so we can avoid
        # looking for an attribute when we have found a datapoint by name on
        # an earlier target already.
        combinedDatapoints = {}

        # extraContents can contain paths to other objects that could have
        # metrics or attributes.
        allTargets = getExtraTargets(datasource.extraContexts, context)
        allTargets.append(context)

        # count down to the last target
        hasMore = len(allTargets)

        for target in allTargets:
            hasMore -= 1

            allDatapointsByVarName = {}
            for dp in target.getRRDDataPoints():
                allDatapointsByVarName[dp.id] = dp
                allDatapointsByVarName[dp.name()] = dp
            combinedDatapoints.update(allDatapointsByVarName)

            for att in getVarNames(datasource.expression):

                if att in allDatapointsByVarName:
                    datapoint = allDatapointsByVarName[att]
                    fqdpn = '%s_%s' % (datapoint.datasource().id, datapoint.id)
                    targetDatapoints[fqdpn] = (
                        datapoint.datasource().id,
                        datapoint.id,
                        'AVERAGE',
                        datasource.targetAsRate,
                        [targetInfo(target)])

                elif att not in combinedDatapoints:
                    value = dotTraverse(target, att)
                    if not CalculatedDataSourcePlugin.isPicklable(value):
                        LOG.error(
                            "Calculated Performance expression %s references "
                            "invalid attribute (unpicklable value) %s",
                            datasource.expression, att)
                        return config

                    # Only store None if we finished and never found
                    # a more interesting value.
                    if value is not None:
                        attrs[att] = value
                    elif att not in attrs and not hasMore:
                        attrs[att] = value
                        LOG.warn(
                            "Calculated Performance expression %s references "
                            "the variable %s which is not in %s on the targets %s",
                            datasource.expression, att,
                            combinedDatapoints.keys(), allTargets)

        config['obj_attrs'] = attrs
        config['targetDatapoints'] = targetDatapoints.values()

        return config