Procházet zdrojové kódy

refactor: 模拟数据上报,采集上报数据修复,测试完整的流程

zhanghaijun před 3 roky
rodič
revize
7251aa61ff

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 137 - 0
docs/postman.json


+ 14 - 7
src/main/java/com/cec/plugins/controller/CollectController.java

@@ -1,14 +1,14 @@
 package com.cec.plugins.controller;
 
-import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.convert.Convert;
 import com.cec.plugins.domain.DtoPolicy;
 import com.cec.plugins.domain.ResultData;
 import com.cec.plugins.enumerate.EstimateEnum;
-import com.cec.plugins.service.RedisClientSource;
 import com.cec.plugins.service.RedisClientEvaluate;
+import com.cec.plugins.service.RedisClientSource;
 import com.cec.plugins.service.TaskService;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.BeanUtils;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -39,7 +39,7 @@ public class CollectController {
     private final RedisClientEvaluate redisClientEvaluate;
     private final TaskService taskService;
 
-    /** 任务状态下发接口 */
+    /** 数据采集配置下发接口 */
     @PostMapping("/sendPolicy")
     public ResultData sendPolicy(@RequestBody @Validated DtoPolicy policy) {
         reportPolicy(policy);
@@ -48,16 +48,22 @@ public class CollectController {
 
     /** 上报采集数据 */
     @Async
-    public void reportPolicy(DtoPolicy policy) {
+    public void reportPolicy(DtoPolicy policyDto) {
         DtoPolicy.ReportPolicy report = new DtoPolicy.ReportPolicy();
+        // 拷贝父类(BaseData)的属性
+        BeanUtils.copyProperties(policyDto, report);
         List<DtoPolicy.ReportPolicyConfig> configList = new ArrayList<>();
-        BeanUtil.copyProperties(policy.getPolicy(), configList, true);
-        for (DtoPolicy.ReportPolicyConfig reportItem : configList) {
-            for (DtoPolicy.ReportPolicyItem item : reportItem.getCollect()) {
+        for (DtoPolicy.PolicyConfig config : policyDto.getPolicy()) {
+            DtoPolicy.ReportPolicyConfig reportItem = new DtoPolicy.ReportPolicyConfig();
+            BeanUtils.copyProperties(config, reportItem);
+            for (DtoPolicy.PolicyItem policy : config.getCollect()) {
+                DtoPolicy.ReportPolicyItem item = new DtoPolicy.ReportPolicyItem();
+                BeanUtils.copyProperties(policy, item);
                 item.setValue(redisClientSource.getCacheStr(item.getKey()));
                 EstimateEnum estimateEnum = EstimateEnum.findEstimateEnum(item.getKey());
                 item.setGroup(Optional.ofNullable(estimateEnum).map(EstimateEnum::getGroup).orElse(""));
                 item.setScore(redisClientEvaluate.getCacheStr(item.getKey()));
+                reportItem.addCollect(item);
             }
             // 计算平均值
             Double avg = reportItem.getCollect().stream()
@@ -65,6 +71,7 @@ public class CollectController {
                 .map(item -> Convert.toDouble(item, 0D))
                 .collect(Collectors.averagingDouble(Double::doubleValue));
             reportItem.setScore(Convert.toStr(avg));
+            configList.add(reportItem);
         }
         report.setData(configList);
         taskService.reportPlatform("/data/api/v1/collectData", report);

+ 0 - 69
src/main/java/com/cec/plugins/controller/TaskController.http

@@ -1,69 +0,0 @@
-### 任务状态下发接口
-POST http://localhost:8080/config/api/v1/taskStatus
-Content-Type: application/json
-
-{
-    "taskId": "01f08470-ae8c-4510-a494-eefe676bcde6",
-    "subtaskId": "da8e68a4-0c31-4131-acfb-e95a4e034abb",
-    "xdschemaId": "7b696138-7a83-4f22-a97f-fbec9f21a3e1",
-    "instanceId": "7e1cb874-ed07-4d10-a980-0eada624b3fb",
-    "ident": "典型轨道交通运行控制网代理插件",
-    "status": 0
-}
-
-### 控制命令下发
-POST http://localhost:8080/config/api/v1/dipatchmission
-Content-Type: application/json
-
-{
-    "taskId": "01f08470-ae8c-4510-a494-eefe676bcde6",
-    "subtaskId": "da8e68a4-0c31-4131-acfb-e95a4e034abb",
-    "xdschemaId": "7b696138-7a83-4f22-a97f-fbec9f21a3e1",
-    "instanceId": "7e1cb874-ed07-4d10-a980-0eada624b3fb",
-    "ident": "典型轨道交通运行控制网代理插件",
-    "commands": 0
-}
-
-### 配置参数下发接口
-POST http://localhost:8080/config/api/v1/dipatchconfigsparam
-Content-Type: application/json
-
-{
-    "taskId": "01f08470-ae8c-4510-a494-eefe676bcde6",
-    "subtaskId": "da8e68a4-0c31-4131-acfb-e95a4e034abb",
-    "xdschemaId": "7b696138-7a83-4f22-a97f-fbec9f21a3e1",
-    "instanceId": "c3330933-29c9-4a6c-a782-ee8b94a6342a",
-    "ident": "典型轨道交通运行控制网代理插件",
-    "paramConfigurations": [
-        {
-            "deviceId": "S/N:1990123456",
-            "config": [
-                {
-                    "name": "布防/撤防",
-                    "key": "deploy",
-                    "value": "0"
-                },
-                {
-                    "name": "接警",
-                    "key": "handlePolice",
-                    "value": "0"
-                }
-            ]
-        },
-        {
-            "deviceId": "S/N:1990123456",
-            "config": [
-                {
-                    "name": "布防/撤防",
-                    "key": "deploy",
-                    "value": "0"
-                },
-                {
-                    "name": "接警",
-                    "key": "handlePolice",
-                    "value": "0"
-                }
-            ]
-        }
-    ]
-}

+ 4 - 4
src/main/java/com/cec/plugins/controller/TaskController.java

@@ -4,7 +4,7 @@ import com.cec.plugins.domain.DtoDipatchconfigsparam;
 import com.cec.plugins.domain.DtoDipatchmission;
 import com.cec.plugins.domain.DtoTaskStatus;
 import com.cec.plugins.domain.ResultData;
-import com.cec.plugins.domain.reported.ReportedData;
+import com.cec.plugins.domain.reported.ReportedTypeFactory;
 import com.cec.plugins.enumerate.TaskEnum;
 import com.cec.plugins.service.TaskService;
 import lombok.RequiredArgsConstructor;
@@ -35,7 +35,7 @@ public class TaskController {
             return ResultData.fail("任务状态保存失败");
         }
         // 异步处理开始上报状态数据( 1、查询 2、上报 )
-        taskService.reported(TaskEnum.TaskInstanceId, ReportedData.ReportedStatus.class);
+        taskService.reported(TaskEnum.TaskInstanceId, ReportedTypeFactory.ReportedStatus.class);
         return ResultData.success();
     }
 
@@ -51,7 +51,7 @@ public class TaskController {
             return ResultData.fail("控制命令保存失败");
         }
         // 异步处理开始上报状态数据( 1、查询 2、上报 )
-        taskService.reported(TaskEnum.ExceCommandInstanceId, ReportedData.ReportedCommand.class);
+        taskService.reported(TaskEnum.ExceCommandInstanceId, ReportedTypeFactory.ReportedCommand.class);
         return ResultData.success();
     }
 
@@ -67,7 +67,7 @@ public class TaskController {
             return ResultData.fail("配置参数保存失败");
         }
         // 异步处理开始上报状态数据( 1、查询 2、上报 )
-        taskService.reported(TaskEnum.ParamConfigInstanceId, ReportedData.ReportedConfig.class);
+        taskService.reported(TaskEnum.ParamConfigInstanceId, ReportedTypeFactory.ReportedConfig.class);
         return ResultData.success();
     }
 }

+ 1 - 1
src/main/java/com/cec/plugins/core/retry/RetryTemplate.java

@@ -44,7 +44,7 @@ public abstract class RetryTemplate {
             } catch (Exception exception) {
                 retryCount++;
                 if (exceptionClass.isInstance(exception)) {
-                    log.warn("Handling failure, 并开始重试, retryCount is {} ,maxRetries is {}, exception is {}", retryCount, maxRetries, exceptionClass.getName());
+                    log.warn("Handling failure, 并开始重试, retryCount is {} ,maxRetries is {}, exception is {}, details: {}", retryCount, maxRetries, exceptionClass.getSimpleName(),exception.getMessage());
                     try {
                         Thread.sleep(retryDelayMillis);
                     } catch (InterruptedException ex) {

+ 6 - 3
src/main/java/com/cec/plugins/domain/DtoPolicy.java

@@ -1,11 +1,10 @@
 package com.cec.plugins.domain;
 
-import cn.hutool.json.JSONArray;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import lombok.ToString;
 
 import javax.validation.constraints.NotNull;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -44,8 +43,12 @@ public class DtoPolicy extends BaseData {
     public static class ReportPolicyConfig {
         private String deviceId;
         private String deviceName;
-        private List<ReportPolicyItem> collect;
+        private List<ReportPolicyItem> collect = new ArrayList<>();
         private String score;
+
+        public void addCollect(ReportPolicyItem item) {
+            this.collect.add(item);
+        }
     }
 
     @Data

+ 2 - 74
src/main/java/com/cec/plugins/domain/reported/ReportedData.java

@@ -29,87 +29,15 @@ public class ReportedData extends BaseData {
     /** 任务执行出错原因 */
     private String reason;
 
-    private final ReportedType reportedType;
-
-    public ReportedData(Class<? extends ReportedType> reportedClass) throws InstantiationException, IllegalAccessException {
-        this.reportedType = reportedClass.newInstance();
-    }
-
-    public TaskEnum getCheckInstanceId() {
-        return reportedType.getInstanceId();
-    }
-
-
-    public Map<TaskEnum, Consumer<String>> getRedisReadMapping() {
+    public Map<TaskEnum, Consumer<String>> getRedisReadMapping(ReportedTypeFactory.ReportedType reportedType) {
         Map<TaskEnum, Consumer<String>> map = new HashMap<>();
         map.put(TaskEnum.TaskId, this::setTaskId);
         map.put(TaskEnum.SubTaskId, this::setSubtaskId);
         map.put(TaskEnum.XdSchemaId, this::setXdschemaId);
-        map.put(TaskEnum.TaskInstanceId, this::setInstanceId);
         map.put(TaskEnum.TaskIdent, this::setIdent);
+        map.put(reportedType.getInstanceId(), this::setInstanceId);
         map.put(reportedType.getStatus(), (status) -> setStatus(Convert.toInt(status, 0)));
         map.put(reportedType.getReason(), this::setReason);
         return map;
     }
-
-    public interface ReportedType {
-        TaskEnum getInstanceId();
-
-        TaskEnum getStatus();
-
-        TaskEnum getReason();
-    }
-
-    public static class ReportedStatus implements ReportedType {
-        @Override
-        public TaskEnum getInstanceId() {
-            return TaskEnum.ExceTaskInstanceId;
-        }
-
-        @Override
-        public TaskEnum getStatus() {
-            return TaskEnum.ExceTaskStatusOrder;
-        }
-
-        @Override
-        public TaskEnum getReason() {
-            return TaskEnum.ExceTaskFailReason;
-        }
-
-
-    }
-
-    public static class ReportedCommand implements ReportedType {
-        @Override
-        public TaskEnum getInstanceId() {
-            return TaskEnum.ExceCommandInstanceId;
-        }
-
-        @Override
-        public TaskEnum getStatus() {
-            return TaskEnum.ExceCommandOrder;
-        }
-
-        @Override
-        public TaskEnum getReason() {
-            return TaskEnum.ExceCommandFailReason;
-        }
-    }
-
-    public static class ReportedConfig implements ReportedType {
-        @Override
-        public TaskEnum getInstanceId() {
-            return TaskEnum.ExceParamConfigInstanceId;
-        }
-
-        @Override
-        public TaskEnum getStatus() {
-            return TaskEnum.ExceParamConfigOrder;
-        }
-
-        @Override
-        public TaskEnum getReason() {
-            return TaskEnum.ExceParamConfigFailReason;
-        }
-    }
 }

+ 0 - 18
src/main/java/com/cec/plugins/domain/reported/ReportedType.java

@@ -1,18 +0,0 @@
-package com.cec.plugins.domain.reported;
-
-import com.cec.plugins.enumerate.TaskEnum;
-
-/**
- * @author zhanghaijun
- * @version 1.0
- * @date 2023/8/18 15:00
- * @description [一句话描述该类的功能]
- */
-public interface ReportedType {
-
-    public TaskEnum getStatus();
-
-    public TaskEnum getReason();
-
-    public TaskEnum getInstanceId();
-}

+ 107 - 0
src/main/java/com/cec/plugins/domain/reported/ReportedTypeFactory.java

@@ -0,0 +1,107 @@
+package com.cec.plugins.domain.reported;
+
+import com.cec.plugins.enumerate.TaskEnum;
+import lombok.Getter;
+
+/**
+ * @author zhanghaijun
+ * @date 2023/8/21 15:30
+ * @description 处理三种类型的上报数据处理
+ */
+@Getter
+public class ReportedTypeFactory {
+
+    private final ReportedTypeFactory.ReportedType reportedType;
+
+    public ReportedTypeFactory(Class<? extends ReportedTypeFactory.ReportedType> reportedClass) throws InstantiationException, IllegalAccessException {
+        this.reportedType = reportedClass.newInstance();
+    }
+
+    public TaskEnum getInstanceId() {
+        return reportedType.getInstanceId();
+    }
+
+    public TaskEnum getOriginInstanceId() {
+        return reportedType.getOriginInstanceId();
+    }
+
+
+    public interface ReportedType {
+        TaskEnum getInstanceId();
+
+        TaskEnum getStatus();
+
+        TaskEnum getReason();
+
+        TaskEnum getOriginInstanceId();
+    }
+
+    public static class ReportedStatus implements ReportedType {
+        @Override
+        public TaskEnum getInstanceId() {
+            return TaskEnum.ExceTaskInstanceId;
+        }
+
+        @Override
+        public TaskEnum getStatus() {
+            return TaskEnum.ExceTaskStatusOrder;
+        }
+
+        @Override
+        public TaskEnum getReason() {
+            return TaskEnum.ExceTaskFailReason;
+        }
+
+        @Override
+        public TaskEnum getOriginInstanceId() {
+            return TaskEnum.TaskInstanceId;
+        }
+
+
+    }
+
+    public static class ReportedCommand implements ReportedType {
+        @Override
+        public TaskEnum getInstanceId() {
+            return TaskEnum.ExceCommandInstanceId;
+        }
+
+        @Override
+        public TaskEnum getStatus() {
+            return TaskEnum.ExceCommandOrder;
+        }
+
+        @Override
+        public TaskEnum getReason() {
+            return TaskEnum.ExceCommandFailReason;
+        }
+
+        @Override
+        public TaskEnum getOriginInstanceId() {
+            return TaskEnum.CommandInstanceId;
+        }
+    }
+
+    public static class ReportedConfig implements ReportedType {
+        @Override
+        public TaskEnum getInstanceId() {
+            return TaskEnum.ExceParamConfigInstanceId;
+        }
+
+        @Override
+        public TaskEnum getStatus() {
+            return TaskEnum.ExceParamConfigOrder;
+        }
+
+        @Override
+        public TaskEnum getReason() {
+            return TaskEnum.ExceParamConfigFailReason;
+        }
+
+        @Override
+        public TaskEnum getOriginInstanceId() {
+            return TaskEnum.ParamConfigInstanceId;
+        }
+    }
+
+}

+ 9 - 7
src/main/java/com/cec/plugins/service/TaskService.java

@@ -9,6 +9,7 @@ import com.cec.plugins.domain.BaseData;
 import com.cec.plugins.domain.ResultData;
 import com.cec.plugins.domain.reported.RegistrationDto;
 import com.cec.plugins.domain.reported.ReportedData;
+import com.cec.plugins.domain.reported.ReportedTypeFactory;
 import com.cec.plugins.domain.reported.ServiceDto;
 import com.cec.plugins.enumerate.TaskEnum;
 import com.cec.plugins.utils.HttpUtils;
@@ -95,7 +96,7 @@ public class TaskService {
 
     /** 上报数据 */
     @Async
-    public void reported(TaskEnum instances,Class<? extends ReportedData.ReportedType> reportedClass) {
+    public void reported(TaskEnum instances, Class<? extends ReportedTypeFactory.ReportedType> reportedClass) {
         try {
             Object data = getReportedData(reportedClass).execute();
             reportPlatform("/config/api/v1/receivetaskstatus", data);
@@ -126,19 +127,20 @@ public class TaskService {
         }
     }
 
-    private RetryTemplate getReportedData(Class<? extends ReportedData.ReportedType> reportedClass) {
+    private RetryTemplate getReportedData(Class<? extends ReportedTypeFactory.ReportedType> reportedClass) {
         ProjectProperties.RetryModel simulation = properties.getSimulation();
         return new RetryTemplate(simulation.getRetries(), simulation.getDelayMillis()) {
             @Override
             protected Object handle() {
                 try {
-                    ReportedData data = new ReportedData(reportedClass);
-                    String instanceId = redisClientSource.getCacheStr(TaskEnum.TaskInstanceId.getKey());
-                    String checkId = redisClientSource.getCacheStr(data.getCheckInstanceId().getKey());
-                    if (!StrUtil.equalsAnyIgnoreCase(instanceId, checkId)) {
+                    ReportedTypeFactory factory = new ReportedTypeFactory(reportedClass);
+                    ReportedData data = new ReportedData();
+                    String originInstanceId = redisClientSource.getCacheStr(factory.getOriginInstanceId().getKey());
+                    String instanceId = redisClientSource.getCacheStr(factory.getInstanceId().getKey());
+                    if (!StrUtil.equalsAnyIgnoreCase(originInstanceId, instanceId)) {
                         throw new RetryException("请求Id不匹配,class:" + reportedClass.getName());
                     }
-                    if (redisClientSource.readRedis(data.getRedisReadMapping())) {
+                    if (redisClientSource.readRedis(data.getRedisReadMapping(factory.getReportedType()))) {
                         return data;
                     }
                     return data;

+ 43 - 72
src/test/java/com/cec/plugins/PluginsApplicationTests.java

@@ -1,92 +1,63 @@
 package com.cec.plugins;
 
+import cn.hutool.core.util.StrUtil;
+import com.cec.plugins.enumerate.EstimateEnum;
+import com.cec.plugins.enumerate.TaskEnum;
+import com.cec.plugins.service.RedisClientEvaluate;
 import com.cec.plugins.service.RedisClientSource;
-import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
-import org.redisson.api.RKeys;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
-import java.util.Optional;
-
 /**
  * {@see 'https://www.cnblogs.com/east7/p/16255305.html'}
  */
 @Slf4j
 @SpringBootTest
-@RequiredArgsConstructor
 class PluginsApplicationTests {
 
-    private final RedisClientSource RedisClientSource;
+    @Autowired
+    private RedisClientSource clientSource;
+    @Autowired
+    private RedisClientEvaluate clientEvaluate;
+
+    @Test
+    void taskStatus() {
+        String instanceId = clientSource.getCacheStr(TaskEnum.TaskInstanceId.getKey());
+        clientSource.setCacheObject(TaskEnum.ExceTaskInstanceId.getKey(), StrUtil.emptyToDefault(instanceId, "7e1cb874-ed07-4d10-a980-taskStatus"));
+        clientSource.setCacheObject(TaskEnum.ExceTaskStatusOrder.getKey(), "1");
+        clientSource.setCacheObject(TaskEnum.ExceTaskFailReason.getKey(), "任务状态-执行成功");
+    }
 
     @Test
-    void contextLoads() {
-        RedisClientSource.setCacheObject("111", "2222");
-        System.out.println(Optional.ofNullable(RedisClientSource.getCacheObject("111")).orElse("--"));
+    void paramConfig() {
+        String instanceId = clientSource.getCacheStr(TaskEnum.ParamConfigInstanceId.getKey());
+        clientSource.setCacheObject(TaskEnum.ExceParamConfigInstanceId.getKey(), StrUtil.emptyToDefault(instanceId, "7e1cb874-ed07-4d10-a980-paramConfig"));
+        clientSource.setCacheObject(TaskEnum.ExceParamConfigOrder.getKey(), "1");
+        clientSource.setCacheObject(TaskEnum.ExceParamConfigFailReason.getKey(), "任务配置-执行成功");
+    }
 
-        RKeys keys = RedisClientSource.getClient().getKeys();
-        // 获取所有key值
-        Iterable<String> allKeys = keys.getKeys();
-        // 模糊查询所有包含关键字key的值
-        Iterable<String> foundedKeys = keys.getKeysByPattern("key");
-        // 删除多个key值
-        long numOfDeletedKeys = keys.delete("obj1", "obj2", "obj3");
-        // 模糊删除key值
-        long deletedKeysAmount = keys.deleteByPattern("test?");
-        // 随机获取key
-        String randomKey = keys.randomKey();
-        // 查询当前有多少个key
-        long keysAmount = keys.count();
+    @Test
+    void command() {
+        String instanceId = clientSource.getCacheStr(TaskEnum.CommandInstanceId.getKey());
+        clientSource.setCacheObject(TaskEnum.ExceCommandInstanceId.getKey(), StrUtil.emptyToDefault(instanceId, "7e1cb874-ed07-4d10-a980-command"));
+        clientSource.setCacheObject(TaskEnum.ExceCommandOrder.getKey(), "1");
+        clientSource.setCacheObject(TaskEnum.ExceCommandFailReason.getKey(), "控制命令-执行成功");
     }
 
-    // private RedisUtils2 redisUtils = null;
-    // private void strDemo() {
-    //     redisUtils.setStr("9999999999", "Hello, String.");
-    //     redisUtils.setStr("myBucket", "myBucketIsXxx");
-    //     RBuckets buckets = redisUtils.getBuckets();
-    //     Map<String, String> foundBuckets = buckets.get("myBucket*");
-    //     Map<String, Object> map = new HashMap<>();
-    //     map.put("myBucket1", "value1");
-    //     map.put("myBucket2", 30L);
-    //
-    //     // 同时保存全部通用对象桶。
-    //     buckets.set(map);
-    //     Map<String, String> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");
-    //     log.info("跨桶String 测试数据:{}", loadedBuckets);
-    //     map.put("myBucket3", 320L);
-    // }
-    //
-    // /** 批量操作 */
-    // private void batchDemo() throws ExecutionException, InterruptedException {
-    //     Map<String, String> map = new HashMap<>();
-    //     map.put("abc", "testStr");
-    //     map.put("abcDemo", "redis");
-    //     redisUtils.setMassStrings(map);
-    //
-    //     log.info("String 测试数据:{}", redisUtils.getStr("abc") + " "
-    //         + redisUtils.getStr("abcDemo"));
-    //
-    //     RBatch batch = redisUtils.createBatch();
-    //     // 模拟购物车场景,真实场景中请替换店铺ID shopId 和商品ID commodityId
-    //     String field = "shopId:commodityId";
-    //     // 把即将执⾏的命令放进 RBatch
-    //     RMapAsync<Object, Object> testMap = batch.getMap("customerId:" + 32L);
-    //     // 更新value,并返回上一次的值
-    //     String commodityNum = "mapValue" + String.valueOf((int) (Math.random() * 9 + 100));
-    //     log.info("当前商品数量commodityNum是:{}", commodityNum);
-    //     testMap.putAsync(field, commodityNum);
-    //     testMap.putAsync("test2", "mapValue3");
-    //     testMap.putAsync("test2", "mapValue5");
-    //     testMap.putAsync("test:" + String.valueOf((int) (Math.random() * 900 + 100)), String.valueOf((int) (Math.random() * 900 + 100)));
-    //
-    //     RAtomicLongAsync counter = batch.getAtomicLong("counter");
-    //
-    //     RFuture<Long> num = counter.incrementAndGetAsync();
-    //
-    //     // 执行RBatch中的全部命令,并返回执行结果
-    //     BatchResult<?> result = batch.execute();
-    //     List<?> list = result.getResponses();
-    //     log.info("Map Batch 执行结果:{}", list);
-    //     log.info("计数器当前值:{}", num.get());
-    // }
+    @Test
+    void estimate() {
+        clientEvaluate.setCacheObject(EstimateEnum.CATS_SendFlow.getKey(), 60);
+        clientEvaluate.setCacheObject(EstimateEnum.CATS_RecFlow.getKey(), 60);
+        clientEvaluate.setCacheObject(EstimateEnum.CISCS_SendFlow.getKey(), 60);
+        clientEvaluate.setCacheObject(EstimateEnum.CISCS_RecFlow.getKey(), 80);
+        clientEvaluate.setCacheObject(EstimateEnum.CVOBC_SendFlow.getKey(), 80);
+        clientEvaluate.setCacheObject(EstimateEnum.CVOBC_RecFlow.getKey(), 80);
+        clientEvaluate.setCacheObject(EstimateEnum.CVOBC_EBLocationMiss.getKey(), 100);
+        clientEvaluate.setCacheObject(EstimateEnum.CVOBC_EBCommMiss.getKey(), 100);
+        clientEvaluate.setCacheObject(EstimateEnum.CATS_MonState.getKey(), 100);
+        clientEvaluate.setCacheObject(EstimateEnum.CATS_DR.getKey(), 100);
+        clientEvaluate.setCacheObject(EstimateEnum.CATS_OTD.getKey(), 100);
+    }
 }

+ 187 - 0
src/test/java/com/cec/plugins/test/TaskController.http

@@ -0,0 +1,187 @@
+### 任务状态下发接口
+POST http://localhost:8080/config/api/v1/taskStatus
+Content-Type: application/json
+
+{
+    "taskId": "518BB5B8-7551-418A-BFDD-A90C1CC66F03",
+    "subtaskId": "9480300E-7BDF-4D7A-BA64-7A059880A694",
+    "xdschemaId": "C4552850-3D50-4934-9C4A-580CD447CECE",
+    "instanceId": "7e1cb874-ed07-4d10-a980-taskStatus",
+    "ident": "典型轨道交通运行控制网拓扑网络场景",
+    "status": 0
+}
+
+### 控制命令下发
+POST http://localhost:8080/config/api/v1/dipatchmission
+Content-Type: application/json
+
+{
+    "taskId": "518BB5B8-7551-418A-BFDD-A90C1CC66F03",
+    "subtaskId": "9480300E-7BDF-4D7A-BA64-7A059880A694",
+    "xdschemaId": "C4552850-3D50-4934-9C4A-580CD447CECE",
+    "instanceId": "7e1cb874-ed07-4d10-a980-command",
+    "ident": "典型轨道交通运行控制网拓扑网络场景",
+    "commands": 0
+}
+
+### 配置参数下发接口
+POST http://localhost:8080/config/api/v1/dipatchconfigsparam
+Content-Type: application/json
+
+{
+    "taskId": "518BB5B8-7551-418A-BFDD-A90C1CC66F03",
+    "subtaskId": "9480300E-7BDF-4D7A-BA64-7A059880A694",
+    "xdschemaId": "C4552850-3D50-4934-9C4A-580CD447CECE",
+    "instanceId": "7e1cb874-ed07-4d10-a980-paramConfig",
+    "ident": "典型轨道交通运行控制网拓扑网络场景",
+    "paramConfigurations": [
+        {
+            "deviceId": "S/N 1000000001",
+            "config": [
+                {
+                    "name": "中心ATS工作模式",
+                    "key": "ParamConfig_CATS_Mode",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "deviceId": "S/N 1000000004",
+            "config": [
+                {
+                    "name": "车站ATS上行站台扣车状态",
+                    "key": "ParamConfig_LATS_UpKCStatus",
+                    "value": "0"
+                },
+                {
+                    "name": "车站ATS下行站台扣车状态",
+                    "key": "ParamConfig_CLATS_DownKCStatus",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "deviceId": "S/N 1000000002",
+            "config": [
+                {
+                    "name": "中心综合监控通风模式",
+                    "key": "ParamConfig_CISCSTFMode",
+                    "value": "0"
+                },
+                {
+                    "name": "中心综合监控FAS联动模式",
+                    "key": "ParamConfig_CISCSFASMode",
+                    "value": "0"
+                },
+                {
+                    "name": "中心综合监控AFC工作模式",
+                    "key": "ParamConfig_CISCSAFCMode",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "deviceId": "S/N 1000000005",
+            "config": [
+                {
+                    "name": "车站综合监控电扶梯状态",
+                    "key": "ParamConfig_LISCSDFTMode",
+                    "value": "0"
+                },
+                {
+                    "name": "车站综合监控给排水水泵状态",
+                    "key": "ParamConfig_LISCSGPSMode",
+                    "value": "0"
+                }
+            ]
+        }
+    ]
+}
+
+### 数据采集配置下发
+POST http://localhost:8080/config/api/v1/sendPolicy
+Content-Type: application/json
+
+{
+    "taskId": "518BB5B8-7551-418A-BFDD-A90C1CC66F03",
+    "subtaskId": "9480300E-7BDF-4D7A-BA64-7A059880A694",
+    "xdschemaId": "C4552850-3D50-4934-9C4A-580CD447CECE",
+    "instanceId": "7e1cb874-ed07-4d10-a980-888888888888",
+    "ident": "典型轨道交通运行控制网拓扑网络场景",
+    "policy": [
+        {
+            "deviceId": "S/N 1000000001",
+            "deviceName": "物联网采集数据",
+            "collect": [
+                {
+                    "key": "CATS_SendFlow",
+                    "name": "中心ATS发送网络流量",
+                    "value": "0"
+                },
+                {
+                    "key": "CATS_RecFlow",
+                    "name": "中心ATS接收网络流量",
+                    "value": "0"
+                },
+                {
+                    "key": "CATS_MonState",
+                    "name": "中心ATS监控状态",
+                    "value": "0"
+                },
+                {
+                    "key": "CATS_DR",
+                    "name": "中心ATS时刻表兑现率",
+                    "value": "0"
+                },
+                {
+                    "key": "CATS_OTD",
+                    "name": "中心ATS时刻表准点率",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "deviceId": "S/N 1000000002",
+            "deviceName": "物联网采集数据",
+            "collect": [
+                {
+                    "key": "CISCS_SendFlow",
+                    "name": "中心ISCS发送网络流量",
+                    "value": "0"
+                },
+                {
+                    "key": "CISCS_RecFlow",
+                    "name": "中心ISCS接收网络流量",
+                    "value": "0"
+                }
+            ]
+        },
+        {
+            "deviceId": "S/N 1000000007",
+            "deviceName": "物联网采集数据",
+            "collect": [
+                {
+                    "key": "CVOBC_SendFlow",
+                    "name": "车载驾驶仿真系统发送网络流量",
+                    "value": "0"
+                },
+                {
+                    "key": "CVOBC_RecFlow",
+                    "name": "车载驾驶仿真系统接收网络流量",
+                    "value": "0"
+                },
+                {
+                    "key": "CVOBC_EBLocationMiss",
+                    "name": "列车紧急制动-定位丢失",
+                    "value": "0"
+                },
+                {
+                    "key": "CVOBC_EBCommMiss",
+                    "name": "列车紧急制动-车地通信",
+                    "value": "0"
+                }
+            ]
+        }
+    ]
+}
+