com.hina.sdk.event.EventHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of HinaCloudSDK Show documentation
Show all versions of HinaCloudSDK Show documentation
The official Java SDK of Hina Analytics
The newest version!
package com.hina.sdk.event;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hina.sdk.HinaSdk;
import com.hina.sdk.exception.HinaException;
import com.hina.sdk.exception.HinaExceptionEnum;
import com.hina.sdk.util.GzipUtil;
import com.hina.sdk.util.IdUtil;
import com.hina.sdk.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
/**
* 事件处理
*/
@Slf4j
public class EventHandler {
private static EventHandler eventHandler;
private EventHandler() {
}
public static synchronized EventHandler getInstance() {
if (eventHandler == null) {
eventHandler = new EventHandler();
}
return eventHandler;
}
// 事件记录
private List staticEventRecords = new ArrayList<>();
/**
* 发送事件,单条模式
*/
public void sendOne(EventReq req) throws HinaException {
try {
EventRecord eventRecord = buildEventRecord(req);
List eventRecords = new ArrayList<>();
eventRecords.add(eventRecord);
sendRecords(eventRecords);
} catch (Exception e) {
throw new HinaException(e);
}
}
/**
* 发送事件,批量模式
*/
public void sendBatch(EventReq req) throws HinaException {
String json = null;
try {
EventRecord eventRecord = buildEventRecord(req);
synchronized (staticEventRecords) {
eventRecord.set_track_id(IdUtil.generateId());
staticEventRecords.add(eventRecord);
if (staticEventRecords.size() >= HinaSdk.getBatch()) {
sendRecords(staticEventRecords);
json = list2json(staticEventRecords);
log.debug("HINA_Java_SDK 发送成功,个数:{},请求参数:{},",staticEventRecords.size(),json);
staticEventRecords.clear();
}
}
} catch (Exception e) {
log.error("HINA_Java_SDK 发送失败,请求参数:{}", json);
throw new HinaException(e);
}
}
/**
* 多条记录
*
* @param records
* @throws IOException
* @throws HinaException
*/
private void sendRecords(List records) throws Exception {
BodyAndJson bodyAndJson = getRequestBody(records);
String url = HinaSdk.getUrl();
post(url, bodyAndJson.getBody());
}
/**
* 单条记录
*/
public void sendRecord(EventRecord eventRecord) throws Exception {
List eventRecords = new ArrayList<>();
eventRecords.add(eventRecord);
sendRecords(eventRecords);
}
/**
* 强制清空队列
*/
public void flush() throws HinaException {
String json = null;
try {
synchronized (staticEventRecords) {
if (staticEventRecords.size() > 0) {
json = list2json(staticEventRecords);
sendRecords(staticEventRecords);
log.debug("HINA_Java_SDK 发送成功,发送个数:{},请求参数:{}", staticEventRecords.size(), json);
staticEventRecords.clear();
}
}
} catch (Exception e) {
log.error("HINA_Java_SDK 发送失败,请求参数:{}", json);
throw new HinaException(e);
}
}
/**
* 构建事件记录
*
* @return
*/
private EventRecord buildEventRecord(EventReq req) {
EventRecord eventRecord = new EventRecord();
if (req.isLogin()) {
String account_id = req.getUserUid();
eventRecord.setAccount_id(account_id);
} else {
String anonymous_id = req.getUserUid();
eventRecord.setAnonymous_id(anonymous_id);
}
eventRecord.setType(req.getType());
eventRecord.setTime(String.valueOf(req.getTime()));
eventRecord.setSend_time(String.valueOf(System.currentTimeMillis()));
eventRecord.setEvent(req.getEventName());
Map map = new HashMap<>();
map.put("H_timezone_offset", "-480");
map.putAll(req.getSuperProperties());
map.putAll(req.getData());
map.put("H_lib", "Java");
map.put("H_lib_version", "6.2.2");
eventRecord.setProperties(map);
return eventRecord;
}
private String list2json(List records) throws JsonProcessingException {
ObjectMapper mapper = JsonUtil.getObjectMapper();
String json = mapper.writeValueAsString(records);
return json;
}
/**
* 获取请求body
*
* @param records
* @return
* @throws JsonProcessingException
* @throws UnsupportedEncodingException
*/
private BodyAndJson getRequestBody(List records) throws IOException {
String json = list2json(records);
if ("dev".equals(HinaSdk.getMode())) log.info(json);
String zipstr = GzipUtil.zip(json);
StringBuilder body = new StringBuilder("gzip=1&data=");
body.append(zipstr);
String bodystr = body.toString();
BodyAndJson instance = BodyAndJson.getInstance(bodystr, json);
return instance;
}
/**
* 发送请求
*/
private void post(String url, String body) throws Exception {
CloseableHttpResponse response = null;
String responseBody = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
if ("dev".equals(HinaSdk.getMode())) log.info(body);
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(body));
httpPost.setHeader("Content-Type", "text/plain");
httpPost.setHeader("Accept", "application/json");
response = httpClient.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
if (null != responseEntity) {
int statusCode = response.getStatusLine().getStatusCode();
responseBody = EntityUtils.toString(responseEntity);
log.debug("HINA_Java_SDK 响应参数:{}",responseBody);
boolean resultIsSuccess = resultIsSuccess(statusCode, responseBody);
if (false == resultIsSuccess) {
throw new HinaException(HinaExceptionEnum.EVENT_FAIL);
}
}
} catch (Exception e){
log.error("HINA_Java_SDK 发送失败,请求参数:{},响应参数:{}", body, responseBody, e);
throw e;
}
finally {
if (null != response) {
response.close();
}
httpClient.close();
}
}
/**
* 判断响应是否成功
*
* @return
*/
private boolean resultIsSuccess(int statusCode, String responseBody) throws IOException {
if (statusCode != 200) return false;
ObjectMapper objectMapper = JsonUtil.getObjectMapper();
EventRes eventRes = objectMapper.readValue(responseBody, EventRes.class);
if (null == eventRes) return false;
if (200 != eventRes.getStatus() || true != eventRes.getSuccess()) return false;
return true;
}
}