CachedDiscoveryService extends DefaultService implements DiscoveryService { @Override public List<MetricQuery> getMatchingQueries(MetricQuery query) { requireNotDisposed(); SystemAssert.requireArgument(query != null, "MetricQuery cannot be null."); long start = System.nanoTime(); List<MetricQuery> queries = new ArrayList<>(); if(DiscoveryService.isWildcardQuery(query)) { String value = _cacheService.get(_getKey(query)); if(value == null) { _logger.debug(MessageFormat.format("CACHE MISS for Wildcard Query: {0}. Will read from persistent storage.", query)); queries = _discoveryService.getMatchingQueries(query); long timeToGetQueriesMillis = (System.nanoTime() - start) / 1000000; _logger.debug("Time to get matching queries from store in ms: " + timeToGetQueriesMillis); if(timeToGetQueriesMillis > UPPER_LIMIT_TIME_GET_QUERIES_IN_MILLIS){ _logger.warn("Long time to get matching queries in ms: {} for query {}", timeToGetQueriesMillis, query); } _executorService.submit(new CacheInsertWorker(query, queries)); } else { _logger.debug(MessageFormat.format("CACHE HIT for Wildcard Query: {0}", query)); _logger.debug("Time to get matching queries from cache in ms: " + (System.nanoTime() - start) / 1000000); try { JavaType type = MAPPER.getTypeFactory().constructCollectionType(List.class, MetricQuery.class); List<MetricQuery> matchedQueries = MAPPER.readValue(value, type); _checkIfExceedsLimits(query, matchedQueries); for(int i=0; i<matchedQueries.size(); i++) { MetricQuery q = new MetricQuery(query); q.setShowHistogramBuckets(query.getShowHistogramBuckets()); q.setPercentile((query.getPercentile())); _replaceWildcardFieldsFromCachedQuery(matchedQueries.get(i), q); queries.add(q); } } catch (IOException e) { _logger.warn("IOException when trying to deserialize cached data into metric queries. Will read from persistent storage.", e); queries = _discoveryService.getMatchingQueries(query); _executorService.submit(new CacheInsertWorker(query, queries)); } } } else { _logger.debug(MessageFormat.format("MetricQuery {0} does not have any wildcards", query)); queries.add(query); } return queries; } @Inject  CachedDiscoveryService(CacheService cacheService, @NamedBinding DiscoveryService discoveryService, SystemConfiguration config, MonitorService monitorService); @Override void dispose(); @Override List<MetricSchemaRecord> filterRecords(SchemaQuery query); @Override List<MetricSchemaRecord> getUniqueRecords(MetricSchemaRecordQuery query, RecordType type); @Override List<String> browseRecords(MetricSchemaRecordQuery query, RecordType type, int indexLevel); @Override List<MetricQuery> getMatchingQueries(MetricQuery query);  }
@Test public void testWildcardExpansionWithinLimit() { CacheService cacheServiceMock = mock(CacheService.class); when(cacheServiceMock.get(anyString())).thenReturn(CACHED_QUERIES); DiscoveryService discoveryServiceMock = mock(DiscoveryService.class); CachedDiscoveryService service = new CachedDiscoveryService(cacheServiceMock, discoveryServiceMock, system.getConfiguration(), null); List<MetricQuery> queries = service.getMatchingQueries(new MetricQuery("scope*", "metric", null, System.currentTimeMillis() - (30 * 24 * 60 * 60 * 1000L), System.currentTimeMillis())); assertEquals(30, queries.size()); }
@Test(expected = WildcardExpansionLimitExceededException.class) public void testWildcardExpansionExceedingLimit() { CacheService cacheServiceMock = mock(CacheService.class); when(cacheServiceMock.get(anyString())).thenReturn(CACHED_QUERIES); DiscoveryService discoveryServiceMock = mock(DiscoveryService.class); CachedDiscoveryService service = new CachedDiscoveryService(cacheServiceMock, discoveryServiceMock, system.getConfiguration(), null); service.getMatchingQueries(new MetricQuery("scope*", "metric", null, System.currentTimeMillis() - (300 * 24 * 60 * 60 * 1000L), System.currentTimeMillis())); }