public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content,
            long lastModifiedTs, String encryptedDataKey4Tag) {
        final String groupKey = GroupKey2.getKey(dataId, group, tenant);
        
        makeSure(groupKey, null);
        final int lockResult = tryWriteLock(groupKey);
        
        if (lockResult < 0) {
            DUMP_LOG.warn("[dump-tag-error] write lock failed. {}", groupKey);
            return false;
        }
        
        try {
            
            //check timestamp
            long localTagLastModifiedTs = ConfigCacheService.getTagLastModifiedTs(groupKey, tag);
            
            boolean timestampOutdated = lastModifiedTs < localTagLastModifiedTs;
            if (timestampOutdated) {
                DUMP_LOG.warn("[dump-tag-ignore] timestamp is outdated,groupKey={}", groupKey);
                return true;
            }
            
            boolean timestampChanged = lastModifiedTs > localTagLastModifiedTs;
            
            final String md5 = MD5Utils.md5Hex(content, ENCODE_UTF8);
            
            String localContentTagMd5 = ConfigCacheService.getContentTagMd5(groupKey, tag);
            boolean md5Changed = !md5.equals(localContentTagMd5);
            
            if (md5Changed) {
                ConfigDiskServiceFactory.getInstance().saveTagToDisk(dataId, group, tenant, tag, content);
            }
            
            if (md5Changed) {
                DUMP_LOG.warn(
                        "[dump-tag] md5 changed, update local jvm cache, groupKey={},tag={}, newMd5={},oldMd5={},lastModifiedTs={}",
                        groupKey, tag, md5, localContentTagMd5, lastModifiedTs);
                updateTagMd5(groupKey, tag, md5, lastModifiedTs, encryptedDataKey4Tag);
            } else if (timestampChanged) {
                DUMP_LOG.warn(
                        "[dump-tag] timestamp changed, update last modified in local jvm cache, groupKey={},tag={},"
                                + "tagLastModifiedTs={},oldTagLastModifiedTs={}", groupKey, tag, lastModifiedTs,
                        localTagLastModifiedTs);
                updateTagTimeStamp(groupKey, tag, lastModifiedTs);
                
            } else {
                DUMP_LOG.warn("[dump-tag-ignore] md5 & timestamp not changed. groupKey={},tag={}", groupKey, tag);
            }
            return true;
        } catch (IOException ioe) {
            DUMP_LOG.error("[dump-tag-exception] save disk error. " + groupKey + ", " + ioe.toString(), ioe);
            return false;
        } finally {
            releaseWriteLock(groupKey);
        }
    }
@Test
    void testDumpTag() throws Exception {
        String dataId = "dataIdtestDumpTag133323";
        String group = "group11";
        String tenant = "tenant112";
        String content = "mockContnet11";
        String tag = "tag12345";
        String groupKey = GroupKey2.getKey(dataId, group, tenant);
        String encryptedDataKey = "key12345";
        long ts = System.currentTimeMillis();
        
        //init dump tag
        boolean dumpTagResult = ConfigCacheService.dumpTag(dataId, group, tenant, tag, content, ts, encryptedDataKey);
        assertTrue(dumpTagResult);
        Mockito.verify(configDiskService, times(1)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(content));
        CacheItem contentCache = ConfigCacheService.getContentCache(groupKey);
        ConfigCache configCacheTag = contentCache.getConfigCacheTags().get(tag);
        assertEquals(ts, configCacheTag.getLastModifiedTs());
        String md5 = MD5Utils.md5Hex(content, "UTF-8");
        assertEquals(md5, configCacheTag.getMd5Utf8());
        
        //ts newer ,md5 update
        long tsNew = System.currentTimeMillis();
        String contentNew = content + tsNew;
        String md5New = MD5Utils.md5Hex(contentNew, "UTF-8");
        boolean resultNew = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentNew, tsNew, encryptedDataKey);
        assertTrue(resultNew);
        assertEquals(md5New, configCacheTag.getMd5Utf8());
        assertEquals(tsNew, configCacheTag.getLastModifiedTs());
        assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey());
        Mockito.verify(configDiskService, times(1)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(contentNew));
        
        //ts old ,md5 update
        long tsOld = tsNew - 1;
        String contentWithOldTs = "contentWithOldTs" + tsOld;
        boolean resultOld = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithOldTs, tsOld, encryptedDataKey);
        assertTrue(resultOld);
        assertEquals(md5New, configCacheTag.getMd5Utf8());
        assertEquals(tsNew, configCacheTag.getLastModifiedTs());
        assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey());
        Mockito.verify(configDiskService, times(0)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(contentWithOldTs));
        
        //ts new only,md5 not update
        long tsNew2 = tsNew + 1;
        String contentWithPrev2 = contentNew;
        boolean resultNew2 = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithPrev2, tsNew2, encryptedDataKey);
        assertTrue(resultNew2);
        assertEquals(md5New, configCacheTag.getMd5Utf8());
        assertEquals(tsNew2, configCacheTag.getLastModifiedTs());
        assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey());
        
        //ts not update,md5 not update
        long tsNew3 = tsNew2;
        String contentWithPrev3 = contentNew;
        boolean resultNew3 = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithPrev3, tsNew3, encryptedDataKey);
        assertTrue(resultNew3);
        assertEquals(md5New, configCacheTag.getMd5Utf8());
        assertEquals(tsNew3, configCacheTag.getLastModifiedTs());
        assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey());
        
        //test remove
        boolean removeTag = ConfigCacheService.removeTag(dataId, group, tenant, tag);
        assertTrue(removeTag);
        Mockito.verify(configDiskService, times(1)).removeConfigInfo4Tag(dataId, group, tenant, tag);
        Map<String, ConfigCache> configCacheTags = ConfigCacheService.getContentCache(groupKey).getConfigCacheTags();
        assertNull(configCacheTags);
    }