ars.module.system.service.AbstractSubscribeService Maven / Gradle / Ivy
package ars.module.system.service;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.List;
import java.util.HashMap;
import java.io.Serializable;
import org.apache.http.client.methods.HttpUriRequest;
import ars.util.Beans;
import ars.server.Servers;
import ars.invoke.remote.Remotes;
import ars.invoke.remote.Protocol;
import ars.invoke.request.Requester;
import ars.invoke.event.InvokeEvent;
import ars.invoke.event.InvokeListener;
import ars.invoke.channel.http.Https;
import ars.invoke.event.InvokeAfterEvent;
import ars.invoke.event.InvokeErrorEvent;
import ars.invoke.event.InvokeBeforeEvent;
import ars.invoke.event.InvokeCompleteEvent;
import ars.module.system.model.Message;
import ars.module.system.model.Subscribe;
import ars.module.system.service.SubscribeService;
import ars.database.repository.Repository;
import ars.database.repository.Repositories;
import ars.database.service.StandardGeneralService;
import ars.server.timer.AbstractTimerServer;
/**
* 请求订阅业务操作抽象实现
*
* @author yongqiangwu
*
* @param
* 数据模型
*/
public abstract class AbstractSubscribeService extends StandardGeneralService
implements SubscribeService, InvokeListener {
private int batch = 1000; // 消息同步批次
private Map subscribes; // 请求订阅资源定制/订阅实体映射
public AbstractSubscribeService() {
this.initRefreshServer();
}
public int getBatch() {
return batch;
}
public void setBatch(int batch) {
if (batch < 1) {
throw new IllegalArgumentException("Illegal batch:" + batch);
}
this.batch = batch;
}
/**
* 初始化消息刷新服务
*/
protected void initRefreshServer() {
new AbstractTimerServer() {
@Override
protected void execute() throws Exception {
refresh();
}
}.start();
}
/**
* 初始化请求订阅缓存
*/
protected void initSubscribeCache() {
if (this.subscribes == null) {
List subscribes = this.getRepository().query().list();
this.subscribes = new HashMap(subscribes.size());
for (T subscribe : subscribes) {
this.subscribes.put(subscribe.getTarget(), subscribe);
}
}
}
/**
* 获取当前请求对应对应的请求订阅对象
*
* @param requester
* 请求对象
* @return 请求订阅对象
*/
protected T getSubscribe(Requester requester) {
if (this.subscribes == null) {
synchronized (this) {
this.initSubscribeCache();
}
}
return this.subscribes.get(requester.getUri());
}
/**
* 消息推送
*
* @param requester
* 请求对象
* @param subscribe
* 请求订阅对象
* @throws Exception
* 操作异常
*/
protected void push(Requester requester, Subscribe subscribe) throws Exception {
Protocol protocol = subscribe.getProtocol();
String host = subscribe.getHost();
Integer port = subscribe.getPort();
String resource = subscribe.getResource();
if (protocol == Protocol.http || protocol == Protocol.https) {
String url = Https.getUrl(protocol, host, port, resource);
HttpUriRequest httpUriRequest = Https.getHttpUriRequest(url.toString(), Https.Method.POST,
requester.getParameters());
httpUriRequest.addHeader(Https.CONTEXT_TOKEN, requester.getToken().getCode());
httpUriRequest.addHeader(Https.CONTEXT_CLIENT, Remotes.getClient());
Https.getBytes(httpUriRequest);
} else if (protocol == Protocol.ssl || protocol == Protocol.tcp || protocol == Protocol.udp) {
Remotes.invoke(Remotes.getProxy(protocol, host, port), requester.getToken(), resource,
requester.getParameters());
} else {
throw new RuntimeException("Not support protocol:" + protocol);
}
}
/**
* 消息同步(如果消息推送失败则将消息保存到数据库)
*
* @param requester
* 请求对象
* @param subscribe
* 订阅对象
*/
protected void synchron(Requester requester, Subscribe subscribe) {
try {
this.push(requester, subscribe);
} catch (Exception e) {
Servers.logger.error("Message synchronization failure", e);
Repository repository = Repositories.getRepository(Message.class);
Message message = Beans.getInstance(repository.getModel());
message.setSubscribe(subscribe);
message.setRequester(requester);
repository.save(message);
}
}
/**
* 刷新消息(从数据库获取消息并重新推送,推送成功后删除消息实体)
*/
protected void refresh() {
Repository repository = Repositories.getRepository(Message.class);
int count = repository.query().count();
for (int page = 1, total = (int) Math.ceil((double) count / (double) this.batch); page <= total; page++) {
List messages = repository.query().paging(page, this.batch).asc("dateJoined").list();
for (final Message message : messages) {
try {
Servers.submit(new Callable
© 2015 - 2024 Weber Informatics LLC | Privacy Policy