浏览代码

feat:集成easy-es,实现数据对es的插入。通过enable控制是否开启该功能。
1、elasticsearch版本8.15.0
2、需手动初始化索引,播放记录+Netty心跳写入es

lihao16 2 月之前
父节点
当前提交
576f5acb93
共有 17 个文件被更改,包括 361 次插入2 次删除
  1. 9 0
      pom.xml
  2. 3 1
      smsb-admin/src/main/java/org/dromara/SmsbApplication.java
  3. 21 0
      smsb-admin/src/main/resources/application-dev.yml
  4. 1 0
      smsb-common/pom.xml
  5. 23 0
      smsb-common/smsb-common-elasticsearch/pom.xml
  6. 25 0
      smsb-common/smsb-common-elasticsearch/src/main/java/com/inspur/elasticsearch/ActuatorEnvironmentPostProcessor.java
  7. 17 0
      smsb-common/smsb-common-elasticsearch/src/main/java/com/inspur/elasticsearch/EasyEsConfiguration.java
  8. 2 0
      smsb-common/smsb-common-elasticsearch/src/main/resources/META-INF/spring.factories
  9. 1 0
      smsb-common/smsb-common-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  10. 6 0
      smsb-modules/smsb-netty/pom.xml
  11. 51 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/controller/SmsbEsController.java
  12. 64 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/domain/es/EsSmsbDeviceHeartRecord.java
  13. 69 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/domain/es/EsSmsbSourcePlayRecord.java
  14. 12 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/esmapper/EsSmsbDeviceHeartRecordMapper.java
  15. 12 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/esmapper/EsSmsbSourcePlayRecordMapper.java
  16. 20 1
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/handler/HeartServerHandler.java
  17. 25 0
      smsb-modules/smsb-netty/src/main/java/com/inspur/netty/handler/SourcePlayRecordHandler.java

+ 9 - 0
pom.xml

@@ -57,6 +57,7 @@
         <maven-compiler-plugin.verison>3.11.0</maven-compiler-plugin.verison>
         <maven-surefire-plugin.version>3.1.2</maven-surefire-plugin.version>
         <flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
+        <easy-es.version>3.0.0</easy-es.version>
     </properties>
 
     <profiles>
@@ -358,6 +359,14 @@
                 <version>${revision}</version>
             </dependency>
 
+
+            <!-- easy-es -->
+            <dependency>
+                <groupId>org.dromara.easy-es</groupId>
+                <artifactId>easy-es-boot-starter</artifactId>
+                <version>${easy-es.version}</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 

+ 3 - 1
smsb-admin/src/main/java/org/dromara/SmsbApplication.java

@@ -1,5 +1,6 @@
 package org.dromara;
 
+import org.dromara.easyes.spring.config.EasyEsConfiguration;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@@ -10,7 +11,8 @@ import org.springframework.boot.context.metrics.buffering.BufferingApplicationSt
  * @author Lion Li
  */
 
-@SpringBootApplication(scanBasePackages = {"org.dromara", "com.inspur"})
+// @SpringBootApplication(scanBasePackages = {"org.dromara", "com.inspur"})
+@SpringBootApplication(scanBasePackages = {"org.dromara", "com.inspur"},exclude = {EasyEsConfiguration.class})
 public class SmsbApplication {
 
     public static void main(String[] args) {

+ 21 - 0
smsb-admin/src/main/resources/application-dev.yml

@@ -124,6 +124,27 @@ redisson:
     # 发布和订阅连接池大小
     subscriptionConnectionPoolSize: 50
 
+# es
+easy-es:
+  # 默认为true,若为false时,则认为不启用本框架
+  enable: false
+  # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开
+  address : 192.168.100.5:9200
+  #如果无账号密码则可不配置此行
+  username: elastic
+  #如果无账号密码则可不配置此行
+  password: WG7WVmuNMtM4GwNYkyWH
+  # 兼容开关,默值为认false,若您当前es客户端版本低于7.x,必须设置为true才能使用,es8.x+则可忽略此配置
+  compatible: false
+  # 禁用 SSL 证书验证
+  ssl:
+    verify: false
+  # 指定请求头
+  request-headers:
+    # 指定 Accept 头为 ES 支持的格式
+    Accept: application/json
+
+
 --- # mail 邮件发送
 mail:
   enabled: false

+ 1 - 0
smsb-common/pom.xml

@@ -14,6 +14,7 @@
         <module>smsb-common-social</module>
         <module>smsb-common-core</module>
         <module>smsb-common-doc</module>
+        <module>smsb-common-elasticsearch</module>
         <module>smsb-common-excel</module>
         <module>smsb-common-idempotent</module>
         <module>smsb-common-job</module>

+ 23 - 0
smsb-common/smsb-common-elasticsearch/pom.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.inspur</groupId>
+        <artifactId>smsb-common</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <artifactId>smsb-common-elasticsearch</artifactId>
+
+    <description>
+        elasticsearch搜索引擎服务
+    </description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.dromara.easy-es</groupId>
+            <artifactId>easy-es-boot-starter</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 25 - 0
smsb-common/smsb-common-elasticsearch/src/main/java/com/inspur/elasticsearch/ActuatorEnvironmentPostProcessor.java

@@ -0,0 +1,25 @@
+package com.inspur.elasticsearch;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.env.EnvironmentPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.core.env.ConfigurableEnvironment;
+
+/**
+ * 健康检查配置注入
+ *
+ * @author Hao Li
+ */
+public class ActuatorEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+
+    @Override
+    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+        System.setProperty("management.health.elasticsearch.enabled", "false");
+    }
+
+    @Override
+    public int getOrder() {
+        return Ordered.HIGHEST_PRECEDENCE;
+    }
+
+}

+ 17 - 0
smsb-common/smsb-common-elasticsearch/src/main/java/com/inspur/elasticsearch/EasyEsConfiguration.java

@@ -0,0 +1,17 @@
+package com.inspur.elasticsearch;
+
+import org.dromara.easyes.spring.annotation.EsMapperScan;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+
+/**
+ * easy-es 配置
+ *
+ * @author Lion Li
+ */
+@AutoConfiguration
+@ConditionalOnProperty(value = "easy-es.enable", havingValue = "true")
+@EsMapperScan("com.inspur.**.esmapper")
+public class EasyEsConfiguration {
+
+}

+ 2 - 0
smsb-common/smsb-common-elasticsearch/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,2 @@
+# META-INF/spring.factories
+org.springframework.boot.env.EnvironmentPostProcessor=com.inspur.elasticsearch.ActuatorEnvironmentPostProcessor

+ 1 - 0
smsb-common/smsb-common-elasticsearch/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@@ -0,0 +1 @@
+com.inspur.elasticsearch.EasyEsConfiguration

+ 6 - 0
smsb-modules/smsb-netty/pom.xml

@@ -50,6 +50,12 @@
             <version>${revision}</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.inspur</groupId>
+            <artifactId>smsb-common-elasticsearch</artifactId>
+            <version>${revision}</version>
+        </dependency>
+
         <!-- 阿里JSON解析器 -->
         <dependency>
             <groupId>com.alibaba.fastjson2</groupId>

+ 51 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/controller/SmsbEsController.java

@@ -0,0 +1,51 @@
+package com.inspur.netty.controller;
+
+
+import cn.hutool.json.JSONObject;
+import com.inspur.netty.esmapper.EsSmsbDeviceHeartRecordMapper;
+import com.inspur.netty.esmapper.EsSmsbSourcePlayRecordMapper;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 描述: Es controller
+ * @author lihao16
+ */
+@RestController
+@Validated
+@RequiredArgsConstructor
+@RequestMapping("/es")
+@ConditionalOnProperty(value = "easy-es.enable", havingValue = "true")
+public class SmsbEsController {
+
+    private final static String INDEX_NAME_SOURCE_PLAY_RECORD = "smsb_source_play_record";
+
+    private final static String INDEX_NAME_DEVICE_HEART_RECORD = "smsb_device_heart_record";
+
+    @Autowired
+    private final EsSmsbSourcePlayRecordMapper esSmsbSourcePlayRecordMapper;
+
+    @Autowired
+    private final EsSmsbDeviceHeartRecordMapper esSmsbDeviceHeartRecordMapper;
+
+    @GetMapping("/createIndex")
+    public R<String> createIndex() {
+        JSONObject resultJson = new JSONObject();
+        if (!esSmsbSourcePlayRecordMapper.existsIndex(INDEX_NAME_SOURCE_PLAY_RECORD)) {
+            esSmsbSourcePlayRecordMapper.createIndex();
+            resultJson.set("smsb_source_play_record", "创建成功");
+        }
+        if (!esSmsbDeviceHeartRecordMapper.existsIndex(INDEX_NAME_DEVICE_HEART_RECORD)) {
+            esSmsbDeviceHeartRecordMapper.createIndex();
+            resultJson.set("smsb_device_heart_record", "创建成功");
+        }
+        return R.ok(resultJson.toString());
+    }
+
+}

+ 64 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/domain/es/EsSmsbDeviceHeartRecord.java

@@ -0,0 +1,64 @@
+package com.inspur.netty.domain.es;
+
+import lombok.Data;
+import org.dromara.easyes.annotation.IndexField;
+import org.dromara.easyes.annotation.IndexId;
+import org.dromara.easyes.annotation.IndexName;
+import org.dromara.easyes.annotation.Settings;
+import org.dromara.easyes.annotation.rely.FieldType;
+import org.dromara.easyes.annotation.rely.IdType;
+
+import java.io.Serial;
+
+/**
+ * 设备心跳对象 smsb_device_heart_record
+ *
+ * @author Hao Li
+ * @date 2025-04-28
+ */
+@Data
+@IndexName(value = "smsb_device_heart_record", aliasName = "deviceHeartRecord")
+@Settings(shardsNum = 3, replicasNum = 0)
+public class EsSmsbDeviceHeartRecord {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @IndexId(type = IdType.NONE)
+    private String id;
+
+    /**
+     * 设备唯一标识
+     */
+    private String identifier;
+
+    /**
+     * 设备IP
+     */
+    private String clientIp;
+
+    /**
+     * 心跳类型 1-http 2-Netty
+     */
+    private String heartType;
+
+    /**
+     * 心跳间隔
+     */
+    private String timeInterval;
+
+    /**
+     * 创建时间
+     */
+    @IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private String createTime;
+
+    /**
+     * 租户ID
+     */
+    private String tenantId;
+
+}

+ 69 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/domain/es/EsSmsbSourcePlayRecord.java

@@ -0,0 +1,69 @@
+package com.inspur.netty.domain.es;
+
+import lombok.Data;
+import org.dromara.easyes.annotation.IndexField;
+import org.dromara.easyes.annotation.IndexId;
+import org.dromara.easyes.annotation.IndexName;
+import org.dromara.easyes.annotation.Settings;
+import org.dromara.easyes.annotation.rely.FieldType;
+import org.dromara.easyes.annotation.rely.IdType;
+
+import java.io.Serial;
+
+/**
+ * 资源播放记录对象 smsb_source_play_record
+ *
+ * @author Hao Li
+ * @date 2025-03-28
+ */
+@Data
+@Settings(shardsNum = 3, replicasNum = 0)
+@IndexName(value = "smsb_source_play_record",aliasName = "sourcePlayRecord")
+public class EsSmsbSourcePlayRecord {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @IndexId(type = IdType.NONE)
+    private String id;
+
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+
+    /**
+     * 节目ID
+     */
+    private String itemId;
+
+    /**
+     * 资源ID
+     */
+    private String sourceId;
+
+    /**
+     * 资源类型
+     */
+    private String sourceType;
+
+    /**
+     * 播放时长
+     */
+    private String duration;
+
+    /**
+     * 租户编号
+     */
+    private String tenantId;
+
+    /**
+     * 创建时间
+     */
+    @IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private String createTime;
+
+}

+ 12 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/esmapper/EsSmsbDeviceHeartRecordMapper.java

@@ -0,0 +1,12 @@
+package com.inspur.netty.esmapper;
+
+import com.inspur.netty.domain.es.EsSmsbDeviceHeartRecord;
+import org.dromara.easyes.core.kernel.BaseEsMapper;
+
+/**
+ * es 设备记录
+ *
+ * @author lihao16
+ */
+public interface EsSmsbDeviceHeartRecordMapper extends BaseEsMapper<EsSmsbDeviceHeartRecord> {
+}

+ 12 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/esmapper/EsSmsbSourcePlayRecordMapper.java

@@ -0,0 +1,12 @@
+package com.inspur.netty.esmapper;
+
+import com.inspur.netty.domain.es.EsSmsbSourcePlayRecord;
+import org.dromara.easyes.core.kernel.BaseEsMapper;
+
+/**
+ * es 播放记录
+ *
+ * @author lihao16
+ */
+public interface EsSmsbSourcePlayRecordMapper extends BaseEsMapper<EsSmsbSourcePlayRecord> {
+}

+ 20 - 1
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/handler/HeartServerHandler.java

@@ -5,6 +5,8 @@ import com.inspur.device.domain.vo.SmsbDeviceVo;
 import com.inspur.device.mapper.SmsbDeviceHeartRecordMapper;
 import com.inspur.device.mapper.SmsbDeviceMapper;
 import com.inspur.device.service.ISmsbDeviceService;
+import com.inspur.netty.domain.es.EsSmsbDeviceHeartRecord;
+import com.inspur.netty.esmapper.EsSmsbDeviceHeartRecordMapper;
 import com.inspur.netty.message.push.PushMessageType;
 import com.inspur.netty.message.receive.ReceiveMessageType;
 import com.inspur.netty.util.NettyConstants;
@@ -16,9 +18,11 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.handler.timeout.IdleState;
 import io.netty.handler.timeout.IdleStateEvent;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.DateUtils;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.redis.utils.RedisUtils;
+import org.dromara.easyes.common.property.EasyEsProperties;
 
 import java.nio.charset.Charset;
 import java.util.Map;
@@ -35,6 +39,12 @@ public class HeartServerHandler extends ChannelInboundHandlerAdapter {
 
     private static final ISmsbDeviceService smsbDeviceService = SpringUtils.getBean(ISmsbDeviceService.class);
 
+    private static final EasyEsProperties easyEsProperties = SpringUtils.containsBean("easyEsProperties")
+        ? SpringUtils.getBean(EasyEsProperties.class) : null;
+
+    private static final EsSmsbDeviceHeartRecordMapper esSmsbDeviceHeartRecordMapper = SpringUtils.containsBean("esSmsbDeviceHeartRecordMapper")
+        ? SpringUtils.getBean(EsSmsbDeviceHeartRecordMapper.class) : null;
+
 
     @Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
@@ -93,20 +103,29 @@ public class HeartServerHandler extends ChannelInboundHandlerAdapter {
 
     private void buildAndInsertHeart(String identifier, Long lastNettyHeartTime, Long currentNettyHeartTime) {
         SmsbDeviceHeartRecord smsbDeviceHeartRecord = new SmsbDeviceHeartRecord();
+        EsSmsbDeviceHeartRecord esSmsbDeviceHeartRecord = new EsSmsbDeviceHeartRecord();
         smsbDeviceHeartRecord.setHeartType(2);
+        esSmsbDeviceHeartRecord.setHeartType("2");
         if (lastNettyHeartTime == null) {
             smsbDeviceHeartRecord.setTimeInterval(0L);
+            esSmsbDeviceHeartRecord.setTimeInterval("0");
         }else {
             smsbDeviceHeartRecord.setTimeInterval(currentNettyHeartTime - lastNettyHeartTime);
+            esSmsbDeviceHeartRecord.setTimeInterval(currentNettyHeartTime - lastNettyHeartTime + "");
         }
         smsbDeviceHeartRecord.setIdentifier(identifier);
+        esSmsbDeviceHeartRecord.setIdentifier(identifier);
         // 获取设备信息 缓存中
         SmsbDeviceVo smsbDeviceVo = smsbDeviceService.getDeviceByIdentifier(identifier);
         if (null != smsbDeviceVo) {
             smsbDeviceHeartRecord.setTenantId(smsbDeviceVo.getTenantId());
+            esSmsbDeviceHeartRecord.setTenantId(smsbDeviceVo.getTenantId());
         }
+        esSmsbDeviceHeartRecord.setCreateTime(DateUtils.getTime());
         smsbDeviceHeartRecordMapper.insert(smsbDeviceHeartRecord);
-
+        if (easyEsProperties != null && easyEsProperties.isEnable()) {
+            esSmsbDeviceHeartRecordMapper.insert(esSmsbDeviceHeartRecord);
+        }
     }
     /*@Override
     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

+ 25 - 0
smsb-modules/smsb-netty/src/main/java/com/inspur/netty/handler/SourcePlayRecordHandler.java

@@ -4,6 +4,8 @@ import com.inspur.device.domain.vo.SmsbDeviceVo;
 import com.inspur.device.service.ISmsbDeviceService;
 import com.inspur.device.service.impl.SmsbDeviceServiceImpl;
 import com.inspur.netty.domain.SourcePlayRecord;
+import com.inspur.netty.domain.es.EsSmsbSourcePlayRecord;
+import com.inspur.netty.esmapper.EsSmsbSourcePlayRecordMapper;
 import com.inspur.netty.mapper.SourcePlayRecordMapper;
 import com.inspur.netty.message.push.PushMessageType;
 import com.inspur.netty.message.receive.ReceiveMessageType;
@@ -13,7 +15,9 @@ import io.netty.buffer.Unpooled;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.DateUtils;
 import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.easyes.common.property.EasyEsProperties;
 
 import java.nio.charset.Charset;
 
@@ -29,6 +33,16 @@ public class SourcePlayRecordHandler extends ChannelInboundHandlerAdapter {
 
     private static final ISmsbDeviceService smsbDeviceService = SpringUtils.getBean(SmsbDeviceServiceImpl.class);
 
+    /**
+     * easy-es 配置类
+     */
+    private static final EasyEsProperties easyEsProperties = SpringUtils.containsBean("easyEsProperties")
+        ? SpringUtils.getBean(EasyEsProperties.class) : null;
+
+    private static final EsSmsbSourcePlayRecordMapper esSmsbSourcePlayRecordMapper = SpringUtils.containsBean("esSmsbSourcePlayRecordMapper")
+        ? SpringUtils.getBean(EsSmsbSourcePlayRecordMapper.class) : null;
+
+
     @Override
     public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
         String message = (String) msg;
@@ -44,23 +58,34 @@ public class SourcePlayRecordHandler extends ChannelInboundHandlerAdapter {
             }
             // 保存播放记录
             SourcePlayRecord sourcePlayRecord = new SourcePlayRecord();
+            EsSmsbSourcePlayRecord esSmsbSourcePlayRecord = new EsSmsbSourcePlayRecord();
             // 设备ID
             sourcePlayRecord.setDeviceId(smsbDeviceVo.getId());
+            esSmsbSourcePlayRecord.setDeviceId(smsbDeviceVo.getId().toString());
             try {
                 // 节目ID
                 sourcePlayRecord.setItemId(Long.parseLong(messageArray[4]));
+                esSmsbSourcePlayRecord.setItemId(messageArray[4]);
                 // 资源ID
                 sourcePlayRecord.setSourceId(Long.parseLong(messageArray[5]));
+                esSmsbSourcePlayRecord.setSourceId(messageArray[5]);
                 // 资源类型
                 sourcePlayRecord.setSourceType(Integer.parseInt(messageArray[6]));
+                esSmsbSourcePlayRecord.setSourceType(messageArray[6]);
                 // 播放时长
                 sourcePlayRecord.setDuration(Long.parseLong(messageArray[7]));
+                esSmsbSourcePlayRecord.setDuration(messageArray[7]);
             }catch (Exception e) {
                 log.error("SourcePlayRecordHandler : parse message error :{}", message);
                 return;
             }
             // 租户编号
             sourcePlayRecord.setTenantId(smsbDeviceVo.getTenantId());
+            esSmsbSourcePlayRecord.setTenantId(smsbDeviceVo.getTenantId());
+            esSmsbSourcePlayRecord.setCreateTime(DateUtils.getTime());
+            if (easyEsProperties != null && easyEsProperties.isEnable()) {
+                esSmsbSourcePlayRecordMapper.insert(esSmsbSourcePlayRecord);
+            }
             sourcePlayRecordMapper.insert(sourcePlayRecord);
             // 回复消息
             String playRecordReplay = identifier + PushMessageType.SOURCE_PLAY_RECORD_REPLAY.getValue();