@Override
    public Optional<SelectionContext<VariableMap>> match(SelectionCriteria criteria)
    {
        if (!criteria.getSource().isPresent()) {
            return Optional.empty();
        }
        try {
            String resourceGroupId = dao.getExactMatchResourceGroup(environment, criteria.getSource().get(), criteria.getQueryType().orElse(""));

            Long start = daoOfflineStart.get();
            if (start != null && daoOfflineStart.compareAndSet(start, null)) {
                log.info("Successfully fetched exact match selectors after %s", nanosSince(start));
            }

            if (resourceGroupId == null) {
                return Optional.empty();
            }

            try {
                return Optional.of(new SelectionContext<>(resourceGroupIdCodec.fromJson(resourceGroupId), emptyVariableMap()));
            }
            catch (IllegalArgumentException e) {
                log.warn("Failed to decode resource group from DB: %s", resourceGroupId);
                return Optional.empty();
            }
        }
        catch (JdbiException e) {
            if (daoOfflineStart.compareAndSet(null, System.nanoTime())) {
                log.warn(e, "Failed to fetch exact match resource group selectors");
            }

            return Optional.empty();
        }
    }
@Test
    public void testMatch()
    {
        ResourceGroupId resourceGroupId1 = new ResourceGroupId(ImmutableList.of("global", "test", "user", "insert"));
        ResourceGroupId resourceGroupId2 = new ResourceGroupId(ImmutableList.of("global", "test", "user", "select"));
        dao.insertExactMatchSelector("test", "@test@test_pipeline", INSERT.name(), CODEC.toJson(resourceGroupId1));
        dao.insertExactMatchSelector("test", "@test@test_pipeline", SELECT.name(), CODEC.toJson(resourceGroupId2));

        DbSourceExactMatchSelector selector = new DbSourceExactMatchSelector("test", dao);

        assertEquals(
                selector.match(new SelectionCriteria(true, "testuser", Optional.of("@test@test_pipeline"), ImmutableSet.of("tag"), EMPTY_RESOURCE_ESTIMATES, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty())),
                Optional.empty());

        assertEquals(
                selector.match(new SelectionCriteria(true, "testuser", Optional.of("@test@test_pipeline"), ImmutableSet.of("tag"), EMPTY_RESOURCE_ESTIMATES, Optional.of(INSERT.name()), Optional.empty(), Optional.empty(), Optional.empty())).map(SelectionContext::getResourceGroupId),
                Optional.of(resourceGroupId1));
        assertEquals(
                selector.match(new SelectionCriteria(true, "testuser", Optional.of("@test@test_pipeline"), ImmutableSet.of("tag"), EMPTY_RESOURCE_ESTIMATES, Optional.of(SELECT.name()), Optional.empty(), Optional.empty(), Optional.empty())).map(SelectionContext::getResourceGroupId),
                Optional.of(resourceGroupId2));

        assertEquals(
                selector.match(new SelectionCriteria(true, "testuser", Optional.of("@test@test_pipeline"), ImmutableSet.of("tag"), EMPTY_RESOURCE_ESTIMATES, Optional.of(DELETE.name()), Optional.empty(), Optional.empty(), Optional.empty())),
                Optional.empty());

        assertEquals(
                selector.match(new SelectionCriteria(true, "testuser", Optional.of("@test@test_new"), ImmutableSet.of(), EMPTY_RESOURCE_ESTIMATES, Optional.of(INSERT.name()), Optional.empty(), Optional.empty(), Optional.empty())),
                Optional.empty());
    }