/*****************************************************************************************
Infosistema - OpenBaas
Copyright(C) 2002-2014 Infosistema, S.A.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
www.infosistema.com
info@openbaas.com
Av. José Gomes Ferreira, 11 3rd floor, s.34
Miraflores
1495-139 Algés Portugal
****************************************************************************************/
package infosistema.openbaas.dataaccess.models;
import infosistema.openbaas.data.models.Application;
import infosistema.openbaas.data.models.Certificate;
import infosistema.openbaas.utils.Const;
import infosistema.openbaas.utils.Log;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class NotificationsModel {
// *** CONTRUCTORS *** //
private NotificationsModel() {
JedisPoolConfig poolConf = new JedisPoolConfig();
poolConf.setMaxActive(2);
poolConf.setMaxWait(10000);
pool = new JedisPool(poolConf, Const.getRedisChatServer(),Const.getRedisChatPort());
}
private static NotificationsModel instance = null;
public static NotificationsModel getInstance() {
if (instance == null) instance = new NotificationsModel();
return instance;
}
// *** PRIVATE *** //
private JedisPool pool;
// *** CONSTANTS *** //
private static final int MAXELEMS = 9999999;
private static final String PUSHLIST = "PushList";
private static final String CERT = "Cert";
private static final String DEVICEID = "deviceId";
public static final String DEVICETOKEN = "deviceToken";
public static final String CLIENTID = "clientId";
private static final String LASTREGISTER= "lastRegister";
private static final String USERID= "userId";
private static final String PUSH_BADGES_LIST = "PushBadgesList";
// *** KEYS *** //
private static final String CLIENT_KEY_FORMAT = "%s:"+CERT+":%s";
private static final String DEVICE_KEY_FORMAT = "%s:Device:%s:%s";
private static final String DEVICE_LIST_KEY_FORMAT = "%s_DTList_%s_%s";
private static final String BADGE_VALUE_FORMAT = "%s:_:%s";
//private static final String NOTIFICATION_VALUE_FORMAT = "%s:_:%s:_:%s:_:%s:_:%s:_:%s:_:%s:_:%s:_:";
private static final String NOTIFICATION_VALUE_FORMAT = "%s:_:%s:_:%s";
private String getClientKey(String appId, String clientId) {
return String.format(CLIENT_KEY_FORMAT, appId, clientId);
}
private String getDeviceKey(String appId, String clientId, String deviceToken) {
return String.format(DEVICE_KEY_FORMAT, appId, clientId, deviceToken);
}
private String getDeviceListKey(String appId, String userId, String clientId) {
return String.format(DEVICE_LIST_KEY_FORMAT, appId, userId, clientId);
}
private String getBadgeValue(String appId, String userId) {
return String.format(BADGE_VALUE_FORMAT, appId, userId);
}
private String getNotificationValue(String appId, String userId, String roomId) {
return String.format(NOTIFICATION_VALUE_FORMAT, appId, userId, roomId);
}
// *** CREATE *** //
//device
public Boolean addDeviceId(String appId,String userId, String clientId, String deviceToken) {
Boolean res = false;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
String user = getDeviceUser(appId, clientId, deviceToken);
String deviceListKey = getDeviceListKey(appId, userId, clientId);
if(user!=userId){
jedis.lrem(getDeviceListKey(appId, user, clientId), 0, deviceToken);
} else{
jedis.lrem(deviceListKey, 0, deviceToken);
}
jedis.rpush(deviceListKey, deviceToken);
res = true;
} catch(Exception e){
res = false;
Log.error("", this, "addDeviceId", "Error in addDeviceId to list", e);
} finally {
pool.returnResource(jedis);
}
return res;
}
public Boolean createUpdateDevice(String appId, String userId, String clientId, Device device) {
Boolean res = false;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
Long milliseconds = device.getLastRegister().getTime();
String deviceKey = getDeviceKey(appId, clientId, device.getToken());
jedis.hset(deviceKey, DEVICEID, device.getDeviceId());
jedis.hset(deviceKey, DEVICETOKEN, device.getToken());
jedis.hset(deviceKey, LASTREGISTER, milliseconds.toString());
jedis.hset(deviceKey, USERID, userId);
res = true;
} finally {
pool.returnResource(jedis);
}
return res;
}
//certificate
public Boolean createUpdateCertificate(String appId, Certificate cert) {
Boolean res = false;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
long milliseconds = cert.getCreatedDate().getTime();
String clientKey = getClientKey(appId, cert.getClientId());
jedis.hset(clientKey, Application.APNS_CLIENT_ID, cert.getClientId());
jedis.hset(clientKey, Application.APNS_CERTIFICATION_PATH, cert.getCertificatePath());
jedis.hset(clientKey, Application.APNS_PASSWORD, cert.getAPNSPassword());
jedis.hset(clientKey, Application.CREATION_DATE, String.valueOf(milliseconds));
res = true;
} finally {
pool.returnResource(jedis);
}
return res;
}
//badges
public Boolean setNewBadgesTODO(String appId, String userId) {
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
Boolean res = false;
try {
String value = getBadgeValue(appId, userId);
jedis.lrem(PUSH_BADGES_LIST, 0, value);
jedis.rpush(PUSH_BADGES_LIST, value);
res = true;
} finally {
pool.returnResource(jedis);
}
return res;
}
//notifications
public Boolean setNewNotifications(String appId, String userId, String roomId) {
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
Boolean res = false;
try {
String value = getNotificationValue(appId, userId, roomId);
jedis.lrem(PUSHLIST, 0, value);
jedis.rpush(PUSHLIST, value);
res = true;
} finally {
pool.returnResource(jedis);
}
return res;
}
// *** GET LIST *** //
//device
public List<Device> getDeviceIdList(String appId,String userId, String clientId) {
List<Device> res = new ArrayList<Device>();
List<String> aux = new ArrayList<String>();
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
aux = jedis.lrange(getDeviceListKey(appId, userId, clientId), 0, MAXELEMS);
Iterator<String> it = aux.iterator();
while(it.hasNext()){
res.add(getDevice(appId, clientId, it.next()));
}
} finally {
pool.returnResource(jedis);
}
return res;
}
//certificate
public List<Certificate> getAllCertificateList() {
List<Certificate> res = new ArrayList<Certificate>();
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
Set<String> setCert = jedis.keys("*"+CERT+"*");
Iterator<String> it = setCert.iterator();
while(it.hasNext()){
String str = it.next();
String[] aux = str.split(Const.COLON);
if(aux.length==3)
res.add(getCertificate(aux[0], aux[2]));
}
} finally {
pool.returnResource(jedis);
}
return res;
}
//badges
public List<String> getAllBadgesTODO() {
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
List<String> res = new ArrayList<String>();
try {
res = jedis.lrange(PUSH_BADGES_LIST, 0, MAXELEMS);
if (res.size()>0) jedis.del(PUSH_BADGES_LIST);
} catch (Exception e) {
Log.error("", this, "getAllBadgesTODO", "Error in getAllBadgesTODO redis."+ res.size(), e);
}
finally {
pool.returnResource(jedis);
}
return res;
}
//notifications
public List<String> getAllNotificationsTODO() {
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
List<String> res = new ArrayList<String>();
try {
res = jedis.lrange(PUSHLIST, 0, MAXELEMS);
if(res.size()>0)
jedis.del(PUSHLIST);
} catch (Exception e) {
Log.error("", this, "getAllNotificationsTODO", "Error in getAllNotificationsTODO redis."+ res.size(), e);
}
finally {
pool.returnResource(jedis);
}
return res;
}
// *** GET *** //
//device
public Device getDevice(String appId,String clientId, String deviceToken) {
Device res = new BasicDevice();
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
String deviceKey = getDeviceKey(appId, clientId, deviceToken);
String deviceId = jedis.hget(deviceKey, DEVICEID);
long l = Long.valueOf(jedis.hget(deviceKey, LASTREGISTER));
res.setLastRegister(new Timestamp(l));
res.setToken(deviceToken);
res.setDeviceId(deviceId);
//res.setUserId(userId);
} finally {
pool.returnResource(jedis);
}
return res;
}
public String getDeviceUser(String appId,String clientId, String deviceToken) {
String res = null;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
String userId = jedis.hget(getDeviceKey(appId, clientId, deviceToken), USERID);
res=userId;
} finally {
pool.returnResource(jedis);
}
return res;
}
//certificate
public Certificate getCertificate(String appId, String clientId) {
Certificate res = null;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
String clientKey = getClientKey(appId, clientId);
String path = jedis.hget(clientKey, Application.APNS_CERTIFICATION_PATH);
String pass = jedis.hget(clientKey, Application.APNS_PASSWORD);
long l = Long.valueOf(jedis.hget(clientKey, Application.CREATION_DATE));
res = new Certificate();
res.setClientId(clientId);
res.setCertificatePath(path);
res.setAPNSPassword(pass);
res.setCreatedDate(new Timestamp(l));
res.setAppId(appId);
} finally {
pool.returnResource(jedis);
}
return res;
}
// *** DELETE *** //
//device
public String removeDevice(String appId,String clientId, String deviceToken) {
String res = null;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
String deviceKey = getDeviceKey(appId, clientId, deviceToken);
if(jedis.exists(deviceKey)){
res = jedis.hget(deviceKey, USERID);
jedis.del(deviceKey);
}
} finally {
pool.returnResource(jedis);
}
return res;
}
public Boolean removeDeviceId(String appId,String userId, String clientId, String deviceToken) {
Boolean res = false;
Jedis jedis = pool.getResource();
jedis.auth(Const.getRedisChatPass());
try {
Long a=(long) -1;
a = jedis.lrem(getDeviceListKey(appId, userId, clientId), 0, deviceToken);
if(a>0)
res = true;
} finally {
pool.returnResource(jedis);
}
return res;
}
}