@Override
    public void save(MetricEntity entity) {
        if (entity == null || StringUtil.isBlank(entity.getApp())) {
            return;
        }
        readWriteLock.writeLock().lock();
        try {
            allMetrics.computeIfAbsent(entity.getApp(), e -> new HashMap<>(16))
                    .computeIfAbsent(entity.getResource(), e -> new LinkedHashMap<Long, MetricEntity>() {
                        @Override
                        protected boolean removeEldestEntry(Entry<Long, MetricEntity> eldest) {
                            // Metric older than {@link #MAX_METRIC_LIVE_TIME_MS} will be removed.
                            return eldest.getKey() < TimeUtil.currentTimeMillis() - MAX_METRIC_LIVE_TIME_MS;
                        }
                    }).put(entity.getTimestamp().getTime(), entity);
        } finally {
            readWriteLock.writeLock().unlock();
        }

    }
@Test
    public void testSave() {
        MetricEntity entry = new MetricEntity();
        entry.setApp("testSave");
        entry.setResource("testResource");
        entry.setTimestamp(new Date(System.currentTimeMillis()));
        entry.setPassQps(1L);
        entry.setExceptionQps(1L);
        entry.setBlockQps(0L);
        entry.setSuccessQps(1L);
        inMemoryMetricsRepository.save(entry);
        List<String> resources = inMemoryMetricsRepository.listResourcesOfApp("testSave");
        Assert.assertTrue(resources.size() == 1 && "testResource".equals(resources.get(0)));
    }