xiatian 5 yıl önce
ebeveyn
işleme
fe141c72f1

+ 7 - 1
pom.xml

@@ -1,5 +1,7 @@
 <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<parent>
 		<groupId>cn.com.qmth.examcloud</groupId>
@@ -17,6 +19,10 @@
 			<artifactId>examcloud-web</artifactId>
 			<version>${examcloud.version}</version>
 		</dependency>
+		<dependency>
+			<groupId>org.springframework.kafka</groupId>
+			<artifactId>spring-kafka</artifactId>
+		</dependency>
 	</dependencies>
 
 </project>

+ 51 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/bean/BaseReport.java

@@ -0,0 +1,51 @@
+package cn.com.qmth.examcloud.reports.commons.bean;
+
+import java.util.Date;
+
+public class BaseReport {
+	protected String topic;
+	private Boolean reportOnException=false;
+	private Date reportTime;
+	private String reportHost;
+
+	public Date getReportTime() {
+		return reportTime;
+	}
+
+	public void setReportTime(Date reportTime) {
+		this.reportTime = reportTime;
+	}
+
+	public String getReportHost() {
+		return reportHost;
+	}
+
+	public void setReportHost(String reportHost) {
+		this.reportHost = reportHost;
+	}
+
+	public Boolean getReportOnException() {
+		return reportOnException;
+	}
+
+	public void setReportOnException(Boolean reportOnException) {
+		this.reportOnException = reportOnException;
+	}
+
+	
+	public String getTopic() {
+		return topic;
+	}
+
+	public BaseReport(Boolean reportOnException, Date reportTime, String reportHost) {
+		super();
+		this.reportOnException = reportOnException;
+		this.reportTime = reportTime;
+		this.reportHost = reportHost;
+	}
+
+	public BaseReport() {
+		super();
+	}
+
+}

+ 44 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/bean/LoginStudentReport.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.examcloud.reports.commons.bean;
+
+import java.util.Date;
+
+import cn.com.qmth.examcloud.reports.commons.enums.Topic;
+
+public class LoginStudentReport extends BaseReport {
+	private Long rootOrgId;
+	private Long studentId;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+
+	public Long getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
+
+
+	public LoginStudentReport(Long rootOrgId, Long studentId) {
+		super();
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.topic = Topic.STUDENT_LOGIN.getCode();
+	}
+
+	public LoginStudentReport(Boolean reportOnException, Date reportTime, String reportHost, Long rootOrgId,
+			 Long studentId) {
+		super(reportOnException, reportTime, reportHost);
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.topic = Topic.STUDENT_LOGIN.getCode();
+	}
+
+}

+ 66 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/bean/OnlineExamStudentReport.java

@@ -0,0 +1,66 @@
+package cn.com.qmth.examcloud.reports.commons.bean;
+
+import java.util.Date;
+
+import cn.com.qmth.examcloud.reports.commons.enums.Topic;
+
+public class OnlineExamStudentReport extends BaseReport {
+
+	private Long rootOrgId;
+	private Long studentId;
+	private Long examId;
+	private Long examStudentId;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public Long getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
+
+	public Long getExamId() {
+		return examId;
+	}
+
+	public void setExamId(Long examId) {
+		this.examId = examId;
+	}
+
+	public Long getExamStudentId() {
+		return examStudentId;
+	}
+
+	public void setExamStudentId(Long examStudentId) {
+		this.examStudentId = examStudentId;
+	}
+
+	public OnlineExamStudentReport(Long rootOrgId, Long studentId,
+			Long examId, Long examStudentId) {
+		super();
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.examId = examId;
+		this.examStudentId = examStudentId;
+		this.topic = Topic.EXAM_STUDENT.getCode();
+	}
+
+	public OnlineExamStudentReport(Boolean reportOnException, Date reportTime, String reportHost, Long rootOrgId,
+			Long studentId, Long examId, Long examStudentId) {
+		super(reportOnException, reportTime, reportHost);
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.examId = examId;
+		this.examStudentId = examStudentId;
+		this.topic = Topic.EXAM_STUDENT.getCode();
+	}
+
+}

+ 43 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/bean/OnlineStudentReport.java

@@ -0,0 +1,43 @@
+package cn.com.qmth.examcloud.reports.commons.bean;
+
+import java.util.Date;
+
+import cn.com.qmth.examcloud.reports.commons.enums.Topic;
+
+public class OnlineStudentReport extends BaseReport {
+	private Long rootOrgId;
+	private Long studentId;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public Long getStudentId() {
+		return studentId;
+	}
+
+	public void setStudentId(Long studentId) {
+		this.studentId = studentId;
+	}
+
+
+	public OnlineStudentReport(Long rootOrgId, Long studentId) {
+		super();
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.topic = Topic.STUDENT.getCode();
+	}
+
+	public OnlineStudentReport(Boolean reportOnException, Date reportTime, String reportHost, Long rootOrgId,
+			Long studentId) {
+		super(reportOnException, reportTime, reportHost);
+		this.rootOrgId = rootOrgId;
+		this.studentId = studentId;
+		this.topic = Topic.STUDENT.getCode();
+	}
+
+}

+ 42 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/bean/OnlineUserReport.java

@@ -0,0 +1,42 @@
+package cn.com.qmth.examcloud.reports.commons.bean;
+
+import java.util.Date;
+
+import cn.com.qmth.examcloud.reports.commons.enums.Topic;
+
+public class OnlineUserReport extends BaseReport {
+	private Long rootOrgId;
+	private Long userId;
+
+	public Long getRootOrgId() {
+		return rootOrgId;
+	}
+
+	public void setRootOrgId(Long rootOrgId) {
+		this.rootOrgId = rootOrgId;
+	}
+
+	public Long getUserId() {
+		return userId;
+	}
+
+	public void setUserId(Long userId) {
+		this.userId = userId;
+	}
+
+	public OnlineUserReport(Long rootOrgId, Long userId) {
+		super();
+		this.rootOrgId = rootOrgId;
+		this.userId = userId;
+		this.topic = Topic.USER.getCode();
+	}
+
+	public OnlineUserReport(Boolean reportOnException, Date reportTime, String reportHost, Long rootOrgId,
+			Long userId) {
+		super(reportOnException, reportTime, reportHost);
+		this.rootOrgId = rootOrgId;
+		this.userId = userId;
+		this.topic = Topic.USER.getCode();
+	}
+
+}

+ 37 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/enums/MqType.java

@@ -0,0 +1,37 @@
+package cn.com.qmth.examcloud.reports.commons.enums;
+
+public enum MqType {
+	KAFKA("kafka", "kafka"),
+	ROCKETMQ("rocketmq", "rocketmq"),
+	;
+
+	// ===========================================================================
+
+	/**
+	 * 码
+	 */
+	private String code;
+
+	/**
+	 * 描述
+	 */
+	private String desc;
+
+	/**
+	 * 构造函数
+	 *
+	 * @param desc
+	 */
+	private MqType(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	public String getCode() {
+		return code;
+	}
+}

+ 53 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/enums/Topic.java

@@ -0,0 +1,53 @@
+package cn.com.qmth.examcloud.reports.commons.enums;
+
+public enum Topic {
+	/**
+	 * 学生登录
+	 */
+	STUDENT_LOGIN("STUDENT_LOGIN", "学生登录"),
+
+	/**
+	 * 学生
+	 */
+	STUDENT("STUDENT", "学生"),
+
+	/**
+	 * 考生
+	 */
+	EXAM_STUDENT("EXAM_STUDENT", "考生"),
+
+	/**
+	 * 后台用户
+	 */
+	USER("USER", "后台用户");
+
+	// ===========================================================================
+
+	/**
+	 * 码
+	 */
+	private String code;
+
+	/**
+	 * 描述
+	 */
+	private String desc;
+
+	/**
+	 * 构造函数
+	 *
+	 * @param desc
+	 */
+	private Topic(String code, String desc) {
+		this.code = code;
+		this.desc = desc;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	public String getCode() {
+		return code;
+	}
+}

+ 22 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/handler/KafkaSendResultHandler.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.examcloud.reports.commons.handler;
+
+import org.apache.kafka.clients.producer.ProducerRecord;
+import org.apache.kafka.clients.producer.RecordMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.kafka.support.ProducerListener;
+
+@SuppressWarnings("rawtypes")
+public class KafkaSendResultHandler implements ProducerListener {
+	private final static Logger logger = LoggerFactory.getLogger(KafkaSendResultHandler.class);
+
+    @Override
+    public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata) {
+    	logger.debug("kafka message send success : " + producerRecord.toString());
+    }
+
+    @Override
+    public void onError(ProducerRecord producerRecord, Exception exception) {
+    	logger.error("kafka message send error : " + producerRecord.toString(),exception);
+    }
+}

+ 125 - 0
src/main/java/cn/com/qmth/examcloud/reports/commons/util/ReportsUtil.java

@@ -0,0 +1,125 @@
+package cn.com.qmth.examcloud.reports.commons.util;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+
+import com.alibaba.fastjson.JSON;
+
+import cn.com.qmth.examcloud.commons.util.ThreadLocalUtil;
+import cn.com.qmth.examcloud.reports.commons.bean.BaseReport;
+import cn.com.qmth.examcloud.reports.commons.bean.LoginStudentReport;
+import cn.com.qmth.examcloud.reports.commons.bean.OnlineExamStudentReport;
+import cn.com.qmth.examcloud.reports.commons.bean.OnlineStudentReport;
+import cn.com.qmth.examcloud.reports.commons.bean.OnlineUserReport;
+import cn.com.qmth.examcloud.reports.commons.enums.MqType;
+import cn.com.qmth.examcloud.reports.commons.handler.KafkaSendResultHandler;
+import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
+import cn.com.qmth.examcloud.web.support.SpringContextHolder;
+
+@SuppressWarnings("unchecked")
+public class ReportsUtil {
+	private final static Logger logger = LoggerFactory.getLogger(ReportsUtil.class);
+
+	private final static String key = "report";
+
+	private static KafkaTemplate<String, String> kafkaTemplate;
+
+	private static String mqType = PropertyHolder.getString("$report.mq-type");
+
+	private static Boolean reportEnable = PropertyHolder.getBoolean("$report.enable", false);
+
+	static {
+		if (reportEnable) {
+			if (MqType.KAFKA.getCode().equals(mqType)) {
+				kafkaTemplate = SpringContextHolder.getBean(KafkaTemplate.class);
+				kafkaTemplate.setProducerListener(new KafkaSendResultHandler());
+			} else if (MqType.ROCKETMQ.getCode().equals(mqType)) {
+				// TODO
+			} else {
+				logger.error("no $report.mq-type property config!");
+			}
+		}
+	}
+
+	private static void sendReportKafka(Boolean onException) {
+		List<BaseReport> list = (List<BaseReport>) ThreadLocalUtil.get(key);
+		if (CollectionUtils.isNotEmpty(list)) {
+			for (BaseReport b : list) {
+				if (!onException || (onException && b.getReportOnException())) {
+					try {
+						if (b instanceof OnlineExamStudentReport) {
+							OnlineExamStudentReport ob = (OnlineExamStudentReport) b;
+							kafkaTemplate.send(ob.getTopic(), JSON.toJSONString(b));
+							LoginStudentReport lp = new LoginStudentReport(ob.getRootOrgId(), ob.getStudentId());
+							setReportCommonData(lp);
+							kafkaTemplate.send(lp.getTopic(), JSON.toJSONString(lp));
+						} else if (b instanceof OnlineStudentReport) {
+							OnlineStudentReport ob = (OnlineStudentReport) b;
+							kafkaTemplate.send(ob.getTopic(), JSON.toJSONString(b));
+							LoginStudentReport lp = new LoginStudentReport(ob.getRootOrgId(), ob.getStudentId());
+							setReportCommonData(lp);
+							kafkaTemplate.send(lp.getTopic(), JSON.toJSONString(lp));
+						} else if (b instanceof OnlineUserReport) {
+							OnlineUserReport ob = (OnlineUserReport) b;
+							kafkaTemplate.send(ob.getTopic(), JSON.toJSONString(b));
+						}
+					} catch (Exception e) {
+						logger.error("SendReport Error:" + JSON.toJSONString(b), e);
+					}
+				}
+			}
+			ThreadLocalUtil.set(key, null);
+		}
+	}
+
+	private static void sendReportRocket(Boolean onException) {
+		// TODO
+	}
+
+	public static void report(BaseReport report) {
+		try {
+			if (!reportEnable) {
+				return;
+			}
+			setReportCommonData(report);
+			List<BaseReport> list = (List<BaseReport>) ThreadLocalUtil.get(key);
+			if (list == null) {
+				list = new ArrayList<BaseReport>();
+				ThreadLocalUtil.set(key, list);
+			}
+			list.add(report);
+		} catch (Exception e) {
+			logger.error(JSON.toJSONString(report), e);
+		}
+	}
+
+	public static void sendReport(Boolean onException) {
+		if (MqType.KAFKA.getCode().equals(mqType)) {
+			sendReportKafka(onException);
+		} else if (MqType.ROCKETMQ.getCode().equals(mqType)) {
+			sendReportRocket(onException);
+		} else {
+			logger.error("no $report.mq-type property config!");
+		}
+	}
+
+	private static void setReportCommonData(BaseReport report) {
+		String ip = null;
+		try {
+			InetAddress localHost = Inet4Address.getLocalHost();
+			ip = localHost.getHostAddress();
+		} catch (Exception e) {
+			ip ="";
+		}
+		report.setReportHost(ip);
+		report.setReportTime(new Date());
+	}
+}