public ImmutableMap<String, Pipeline> resolvePipelines(PipelineMetricRegistry pipelineMetricRegistry) {
        final Map<String, Rule> ruleNameMap = resolveRules();

        // Read all pipelines and parse them
        final ImmutableMap.Builder<String, Pipeline> pipelineIdMap = ImmutableMap.builder();
        try (final var pipelineStream = pipelineDaoSupplier.get()) {
            pipelineStream.forEach(pipelineDao -> {
                Pipeline pipeline;
                try {
                    pipeline = ruleParser.parsePipeline(pipelineDao.id(), pipelineDao.source());
                } catch (ParseException e) {
                    LOG.warn("Ignoring non parseable pipeline <{}/{}> with errors <{}>", pipelineDao.title(), pipelineDao.id(), e.getErrors());
                    pipeline = Pipeline.empty("Failed to parse pipeline: " + pipelineDao.id());
                }
                //noinspection ConstantConditions
                pipelineIdMap.put(pipelineDao.id(), resolvePipeline(pipelineMetricRegistry, pipeline, ruleNameMap));
            });
        }

        return pipelineIdMap.build();
    }
@Test
    void resolvePipelines() {
        final var registry = PipelineMetricRegistry.create(metricRegistry, Pipeline.class.getName(), Rule.class.getName());
        final var resolver = new PipelineResolver(
                new PipelineRuleParser(new FunctionRegistry(Map.of())),
                PipelineResolverConfig.of(
                        () -> Stream.of(rule1),
                        () -> Stream.of(pipeline1),
                        () -> Stream.of(connections1, connections2)
                )
        );

        final var pipelines = resolver.resolvePipelines(registry);

        assertThat(pipelines).hasSize(1);
        assertThat(pipelines.get("pipeline-1")).satisfies(pipeline -> {
            assertThat(pipeline.id()).isEqualTo("pipeline-1");
            assertThat(pipeline.name()).isEqualTo("test-pipeline-1");
            assertThat(pipeline.stages()).hasSize(1);
            assertThat(pipeline.stages().first()).satisfies(stage -> {
                assertThat(stage.stage()).isEqualTo(5);
                assertThat(stage.match()).isEqualTo(Stage.Match.EITHER);
                assertThat(stage.ruleReferences()).isEqualTo(List.of("test-rule-1"));
                assertThat(stage.getRules()).hasSize(1);
                assertThat(stage.getRules().get(0)).satisfies(rule -> {
                    assertThat(rule.id()).isEqualTo("rule-1");
                    assertThat(rule.name()).isEqualTo("test-rule-1");
                });
            });
        });

        assertThat(metricRegistry.getMetrics().keySet()).containsExactlyInAnyOrder(
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.pipeline-1.5.not-matched",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.pipeline-1.5.matched",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.pipeline-1.5.failed",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.pipeline-1.5.executed",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.matched",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.not-matched",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.failed",
                "org.graylog.plugins.pipelineprocessor.ast.Rule.rule-1.executed",
                "org.graylog.plugins.pipelineprocessor.ast.Pipeline.pipeline-1.executed",
                "org.graylog.plugins.pipelineprocessor.ast.Pipeline.pipeline-1.stage.5.executed"
        );
    }