private Function getAggregation()

in java/ws-server/src/main/java/com/epam/deltix/tbwg/webapp/services/grafana/FunctionsServiceImpl.java [134:204]


    private Function<GenericRecord, Aggregation> getAggregation(SelectQuery.FunctionDef functionDef, long start, long end, long interval,
                                                                String symbol, List<SelectQuery.TimebaseField> groupBy, int level)
            throws ValidationException {
        Class<? extends Aggregation> clazz = aggregations.get(functionDef.getId(), null);
        if (clazz == null) {
            throw new NoSuchFunctionException(functionDef.getId());
        }
        Constructor<? extends Aggregation> constructor;
        try {
            constructor = clazz.getConstructor(Arguments.class);
        } catch (NoSuchMethodException e) {
            throw new ValidationException(e);
        }

        final Function<GenericRecord, Aggregation> aggregationFunction;

        // actually, if function is in 'aggregations' list on UI (has only on one field arg and is aggregation)
        if (level == 0 && functionDef.getFieldArgs() != null && functionDef.getFieldArgs().size() == 1) {
            SelectQuery.FieldArg arg = functionDef.getFieldArgs().get(0);
            if (arg.getFunction() != null && arg.getFunction().getResultFields() != null
                    && !arg.getFunction().getResultFields().isEmpty()) {
                List<Function<GenericRecord, Aggregation>> aggregations = new ObjectArrayList<>();
                for (Function<GenericRecord, Arguments> arguments : Objects.requireNonNull(extractMultiArguments(
                        arg.getFunction().getResultFields(), functionDef, start, end, interval, symbol, groupBy))) {
                    aggregations.add(record -> {
                        try {
                            return constructor.newInstance(arguments.apply(record));
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    });
                }
                aggregationFunction = record -> new RuntimeJoiningAggregation(aggregations);
            } else {
                Function<GenericRecord, ExtendedArguments> argumentsFunction = extractArguments(functionDef, start, end,
                        interval, symbol, groupBy);
                aggregationFunction = record -> {
                    try {
                        return constructor.newInstance(argumentsFunction.apply(record));
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                };
            }
        } else {
            Function<GenericRecord, ExtendedArguments> argumentsFunction = extractArguments(functionDef, start, end, interval,
                    symbol, groupBy);
            aggregationFunction = record -> {
                try {
                    return constructor.newInstance(argumentsFunction.apply(record));
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            };
        }

        if (functionDef.getFieldArgs() != null && !functionDef.getFieldArgs().isEmpty()) {
            List<SelectQuery.FieldArg> merged = merge(functionDef.getFieldArgs());
            List<Function<GenericRecord, Aggregation>> aggregations = new ObjectArrayList<>();
            for (SelectQuery.FieldArg fieldArg : merged) {
                if (fieldArg.getFunction() != null) {
                    aggregations.add(getAggregation(fieldArg.getFunction(), start, end, interval, symbol, groupBy, level + 1));
                } else {
                    aggregations.add(record -> new PeekFieldAggregation(fieldArg.getField().getName()));
                }
            }
            return record -> new RuntimeJoiningAggregation(aggregations).andThen(aggregationFunction.apply(record));
        }

        return aggregationFunction;
    }