@Override
    public boolean process(NacosTask task) {
        if (!(task instanceof DumpAllTask)) {
            DEFAULT_LOG.error("[all-dump-error] ,invalid task type,DumpAllProcessor should process DumpAllTask type.");
            return false;
        }
        DumpAllTask dumpAllTask = (DumpAllTask) task;
        
        long currentMaxId = configInfoPersistService.findConfigMaxId();
        long lastMaxId = 0;
        ThreadPoolExecutor executorService = null;
        if (dumpAllTask.isStartUp()) {
            executorService = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                    Runtime.getRuntime().availableProcessors(), 60L, TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>(PropertyUtil.getAllDumpPageSize() * 2),
                    r -> new Thread(r, "dump all executor"), new ThreadPoolExecutor.CallerRunsPolicy());
        } else {
            executorService = new ThreadPoolExecutor(1, 1, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(),
                    r -> new Thread(r, "dump all executor"), new ThreadPoolExecutor.CallerRunsPolicy());
        }
        
        DEFAULT_LOG.info("start dump all config-info...");
        
        while (lastMaxId < currentMaxId) {
            
            long start = System.currentTimeMillis();
            
            Page<ConfigInfoWrapper> page = configInfoPersistService.findAllConfigInfoFragment(lastMaxId,
                    PropertyUtil.getAllDumpPageSize(), dumpAllTask.isStartUp());
            long dbTimeStamp = System.currentTimeMillis();
            if (page == null || page.getPageItems() == null || page.getPageItems().isEmpty()) {
                break;
            }
            
            for (ConfigInfoWrapper cf : page.getPageItems()) {
                lastMaxId = Math.max(cf.getId(), lastMaxId);
                //if not start up, page query will not return content, check md5 and lastModified first ,if changed ,get single content info to dump.
                if (!dumpAllTask.isStartUp()) {
                    final String groupKey = GroupKey2.getKey(cf.getDataId(), cf.getGroup(), cf.getTenant());
                    boolean newLastModified = cf.getLastModified() > ConfigCacheService.getLastModifiedTs(groupKey);
                    //check md5 & update local disk cache.
                    String localContentMd5 = ConfigCacheService.getContentMd5(groupKey);
                    boolean md5Update = !localContentMd5.equals(cf.getMd5());
                    if (newLastModified || md5Update) {
                        LogUtil.DUMP_LOG.info("[dump-all] find change config {}, {}, md5={}", groupKey,
                                cf.getLastModified(), cf.getMd5());
                        cf = configInfoPersistService.findConfigInfo(cf.getDataId(), cf.getGroup(), cf.getTenant());
                    } else {
                        continue;
                    }
                }
                
                if (cf == null) {
                    continue;
                }
                if (cf.getDataId().equals(AggrWhitelist.AGGRIDS_METADATA)) {
                    AggrWhitelist.load(cf.getContent());
                }
                
                if (cf.getDataId().equals(ClientIpWhiteList.CLIENT_IP_WHITELIST_METADATA)) {
                    ClientIpWhiteList.load(cf.getContent());
                }
                
                if (cf.getDataId().equals(SwitchService.SWITCH_META_DATA_ID)) {
                    SwitchService.load(cf.getContent());
                }
                
                final String content = cf.getContent();
                final String dataId = cf.getDataId();
                final String group = cf.getGroup();
                final String tenant = cf.getTenant();
                final long lastModified = cf.getLastModified();
                final String type = cf.getType();
                final String encryptedDataKey = cf.getEncryptedDataKey();
                
                executorService.execute(() -> {
                    final String md5Utf8 = MD5Utils.md5Hex(content, ENCODE_UTF8);
                    boolean result = ConfigCacheService.dumpWithMd5(dataId, group, tenant, content, md5Utf8,
                            lastModified, type, encryptedDataKey);
                    if (result) {
                        LogUtil.DUMP_LOG.info("[dump-all-ok] {}, {}, length={},md5UTF8={}",
                                GroupKey2.getKey(dataId, group), lastModified, content.length(), md5Utf8);
                    } else {
                        LogUtil.DUMP_LOG.info("[dump-all-error] {}", GroupKey2.getKey(dataId, group));
                    }
                    
                });
                
            }
            
            long diskStamp = System.currentTimeMillis();
            DEFAULT_LOG.info("[all-dump] submit all task for {} / {}, dbTime={},diskTime={}", lastMaxId, currentMaxId,
                    (dbTimeStamp - start), (diskStamp - dbTimeStamp));
        }
        
        //wait all task are finished and then shutdown executor.
        try {
            int unfinishedTaskCount = 0;
            while ((unfinishedTaskCount = executorService.getQueue().size() + executorService.getActiveCount()) > 0) {
                DEFAULT_LOG.info("[all-dump] wait {} dump tasks to be finished", unfinishedTaskCount);
                Thread.sleep(1000L);
            }
            executorService.shutdown();
            
        } catch (Exception e) {
            DEFAULT_LOG.error("[all-dump] wait  dump tasks to be finished error", e);
        }
        DEFAULT_LOG.info("success to  dump all config-info。");
        return true;
    }
@Test
    void testDumpAllOnCheckAll() throws Exception {
        ConfigInfoWrapper configInfoWrapper1 = createNewConfig(1);
        ConfigInfoWrapper configInfoWrapper2 = createNewConfig(2);
        long timestamp = System.currentTimeMillis();
        configInfoWrapper1.setLastModified(timestamp);
        configInfoWrapper2.setLastModified(timestamp);
        Page<ConfigInfoWrapper> page = new Page<>();
        page.setTotalCount(2);
        page.setPagesAvailable(2);
        page.setPageNumber(1);
        List<ConfigInfoWrapper> list = Arrays.asList(configInfoWrapper1, configInfoWrapper2);
        page.setPageItems(list);
        
        Mockito.when(configInfoPersistService.findConfigMaxId()).thenReturn(2L);
        Mockito.when(configInfoPersistService.findAllConfigInfoFragment(0, PropertyUtil.getAllDumpPageSize(), false)).thenReturn(page);
        
        ConfigInfoWrapper configInfoWrapperSingle1 = new ConfigInfoWrapper();
        BeanUtils.copyProperties(configInfoWrapper1, configInfoWrapperSingle1);
        configInfoWrapperSingle1.setContent("content123456");
        Mockito.when(configInfoPersistService.findConfigInfo(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(),
                configInfoWrapper1.getTenant())).thenReturn(configInfoWrapperSingle1);
        
        ConfigInfoWrapper configInfoWrapperSingle2 = new ConfigInfoWrapper();
        BeanUtils.copyProperties(configInfoWrapper2, configInfoWrapperSingle2);
        configInfoWrapperSingle2.setContent("content123456222");
        Mockito.when(configInfoPersistService.findConfigInfo(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(),
                configInfoWrapper2.getTenant())).thenReturn(configInfoWrapperSingle2);
        
        // For config 1, assign a latter time, to make sure that it would not be updated.
        // For config 2, assign an earlier time, to make sure that it would be updated.
        String md51 = MD5Utils.md5Hex(configInfoWrapper1.getContent(), "UTF-8");
        String md52 = MD5Utils.md5Hex(configInfoWrapper2.getContent(), "UTF-8");
        long latterTimestamp = timestamp + 999;
        long earlierTimestamp = timestamp - 999;
        String encryptedDataKey = "testEncryptedDataKey";
        ConfigCacheService.dumpWithMd5(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), configInfoWrapper1.getTenant(),
                configInfoWrapper1.getContent(), md51, latterTimestamp, "json", encryptedDataKey);
        ConfigCacheService.dumpWithMd5(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), configInfoWrapper2.getTenant(),
                configInfoWrapper2.getContent(), md52, earlierTimestamp, "json", encryptedDataKey);
        
        DumpAllTask dumpAllTask = new DumpAllTask(false);
        boolean process = dumpAllProcessor.process(dumpAllTask);
        
        assertTrue(process);
        
        //Check cache
        CacheItem contentCache1 = ConfigCacheService.getContentCache(
                GroupKey2.getKey(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), configInfoWrapper1.getTenant()));
        // check if config1 is not updated
        assertEquals(md51, contentCache1.getConfigCache().getMd5Utf8());
        assertEquals(latterTimestamp, contentCache1.getConfigCache().getLastModifiedTs());
        //check disk
        String contentFromDisk1 = ConfigDiskServiceFactory.getInstance()
                .getContent(configInfoWrapper1.getDataId(), configInfoWrapper1.getGroup(), configInfoWrapper1.getTenant());
        assertEquals(configInfoWrapper1.getContent(), contentFromDisk1);
        
        //Check cache
        CacheItem contentCache2 = ConfigCacheService.getContentCache(
                GroupKey2.getKey(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), configInfoWrapper2.getTenant()));
        // check if config2 is updated
        assertEquals(MD5Utils.md5Hex(configInfoWrapperSingle2.getContent(), "UTF-8"), contentCache2.getConfigCache().getMd5Utf8());
        assertEquals(configInfoWrapper2.getLastModified(), contentCache2.getConfigCache().getLastModifiedTs());
        //check disk
        String contentFromDisk2 = ConfigDiskServiceFactory.getInstance()
                .getContent(configInfoWrapper2.getDataId(), configInfoWrapper2.getGroup(), configInfoWrapper2.getTenant());
        assertEquals(configInfoWrapperSingle2.getContent(), contentFromDisk2);
    }