aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2017-09-19 22:10:44 +1200
committerGitHub <noreply@github.com>2017-09-19 22:10:44 +1200
commit6a40551d0e1d63fbb68f0401be73a4c64db4ca64 (patch)
tree36e5d835966f0a7d1d5563e24263b87734c86370 /src/org/traccar
parent561c616418918da4bb1d75c95347e25c23f72f6a (diff)
parent285f6feea43be782edc6233b709d47b146250361 (diff)
downloadtraccar-server-6a40551d0e1d63fbb68f0401be73a4c64db4ca64.tar.gz
traccar-server-6a40551d0e1d63fbb68f0401be73a4c64db4ca64.tar.bz2
traccar-server-6a40551d0e1d63fbb68f0401be73a4c64db4ca64.zip
Merge pull request #3534 from Abyss777/extend_notifications
Implement per device Notifications
Diffstat (limited to 'src/org/traccar')
-rw-r--r--src/org/traccar/Context.java3
-rw-r--r--src/org/traccar/api/BaseObjectResource.java2
-rw-r--r--src/org/traccar/api/resource/CommandTypeResource.java4
-rw-r--r--src/org/traccar/api/resource/NotificationResource.java34
-rw-r--r--src/org/traccar/api/resource/UserResource.java3
-rw-r--r--src/org/traccar/database/CommandsManager.java16
-rw-r--r--src/org/traccar/database/DataManager.java3
-rw-r--r--src/org/traccar/database/NotificationManager.java187
-rw-r--r--src/org/traccar/database/PermissionsManager.java11
-rw-r--r--src/org/traccar/model/Notification.java10
-rw-r--r--src/org/traccar/model/Typed.java (renamed from src/org/traccar/model/CommandType.java)4
11 files changed, 86 insertions, 191 deletions
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index 210d52429..340eb742c 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -62,6 +62,7 @@ import org.traccar.model.Device;
import org.traccar.model.Driver;
import org.traccar.model.Geofence;
import org.traccar.model.Group;
+import org.traccar.model.Notification;
import org.traccar.model.User;
import org.traccar.geolocation.GoogleGeolocationProvider;
import org.traccar.geolocation.GeolocationProvider;
@@ -433,6 +434,8 @@ public final class Context {
return (BaseObjectManager<T>) driversManager;
} else if (clazz.equals(Command.class)) {
return (BaseObjectManager<T>) commandsManager;
+ } else if (clazz.equals(Notification.class)) {
+ return (BaseObjectManager<T>) notificationManager;
}
return null;
}
diff --git a/src/org/traccar/api/BaseObjectResource.java b/src/org/traccar/api/BaseObjectResource.java
index f0f31a154..634957a49 100644
--- a/src/org/traccar/api/BaseObjectResource.java
+++ b/src/org/traccar/api/BaseObjectResource.java
@@ -111,8 +111,6 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
if (baseClass.equals(Group.class) || baseClass.equals(Device.class)) {
Context.getPermissionsManager().refreshDeviceAndGroupPermissions();
Context.getPermissionsManager().refreshAllExtendedPermissions();
- } else if (baseClass.equals(User.class) && Context.getNotificationManager() != null) {
- Context.getNotificationManager().refresh();
}
return Response.ok(entity).build();
}
diff --git a/src/org/traccar/api/resource/CommandTypeResource.java b/src/org/traccar/api/resource/CommandTypeResource.java
index 30f9300cb..0a904bd8a 100644
--- a/src/org/traccar/api/resource/CommandTypeResource.java
+++ b/src/org/traccar/api/resource/CommandTypeResource.java
@@ -18,7 +18,7 @@ package org.traccar.api.resource;
import org.traccar.Context;
import org.traccar.api.BaseResource;
-import org.traccar.model.CommandType;
+import org.traccar.model.Typed;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
@@ -34,7 +34,7 @@ import java.util.Collection;
public class CommandTypeResource extends BaseResource {
@GET
- public Collection<CommandType> get(@QueryParam("deviceId") long deviceId,
+ public Collection<Typed> get(@QueryParam("deviceId") long deviceId,
@QueryParam("textChannel") boolean textChannel) {
if (deviceId != 0) {
Context.getPermissionsManager().checkDevice(getUserId(), deviceId);
diff --git a/src/org/traccar/api/resource/NotificationResource.java b/src/org/traccar/api/resource/NotificationResource.java
index dee972607..540f02926 100644
--- a/src/org/traccar/api/resource/NotificationResource.java
+++ b/src/org/traccar/api/resource/NotificationResource.java
@@ -15,7 +15,6 @@
*/
package org.traccar.api.resource;
-import java.sql.SQLException;
import java.util.Collection;
import javax.mail.MessagingException;
@@ -24,14 +23,14 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.traccar.Context;
-import org.traccar.api.BaseResource;
+import org.traccar.api.ExtendedObjectResource;
import org.traccar.model.Event;
import org.traccar.model.Notification;
+import org.traccar.model.Typed;
import org.traccar.notification.NotificationMail;
import org.traccar.notification.NotificationSms;
@@ -40,34 +39,23 @@ import com.cloudhopper.smpp.type.SmppChannelException;
import com.cloudhopper.smpp.type.SmppTimeoutException;
import com.cloudhopper.smpp.type.UnrecoverablePduException;
-@Path("users/notifications")
+@Path("notifications")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
-public class NotificationResource extends BaseResource {
+public class NotificationResource extends ExtendedObjectResource<Notification> {
- @GET
- public Collection<Notification> get(@QueryParam("all") boolean all,
- @QueryParam("userId") long userId) throws SQLException {
- if (all) {
- return Context.getNotificationManager().getAllNotifications();
- }
- if (userId == 0) {
- userId = getUserId();
- }
- Context.getPermissionsManager().checkUser(getUserId(), userId);
- return Context.getNotificationManager().getAllUserNotifications(userId);
+ public NotificationResource() {
+ super(Notification.class);
}
- @POST
- public Response update(Notification entity) throws SQLException {
- Context.getPermissionsManager().checkReadonly(getUserId());
- Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
- Context.getNotificationManager().updateNotification(entity);
- return Response.ok(entity).build();
+ @GET
+ @Path("types")
+ public Collection<Typed> get() {
+ return Context.getNotificationManager().getAllNotificationTypes();
}
- @Path("test")
@POST
+ @Path("test")
public Response testMessage() throws MessagingException, RecoverablePduException,
UnrecoverablePduException, SmppTimeoutException, SmppChannelException, InterruptedException {
NotificationMail.sendMailSync(getUserId(), new Event("test", 0), null);
diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java
index 0eb328ab5..0f6f6edba 100644
--- a/src/org/traccar/api/resource/UserResource.java
+++ b/src/org/traccar/api/resource/UserResource.java
@@ -85,9 +85,6 @@ public class UserResource extends BaseObjectResource<User> {
Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true);
}
Context.getUsersManager().refreshUserItems();
- if (Context.getNotificationManager() != null) {
- Context.getNotificationManager().refresh();
- }
return Response.ok(entity).build();
}
diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java
index deb802b29..521a2e1d1 100644
--- a/src/org/traccar/database/CommandsManager.java
+++ b/src/org/traccar/database/CommandsManager.java
@@ -26,7 +26,7 @@ import org.traccar.BaseProtocol;
import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Command;
-import org.traccar.model.CommandType;
+import org.traccar.model.Typed;
import org.traccar.model.Position;
public class CommandsManager extends ExtendedObjectManager<Command> {
@@ -102,29 +102,29 @@ public class CommandsManager extends ExtendedObjectManager<Command> {
return result;
}
- public Collection<CommandType> getCommandTypes(long deviceId, boolean textChannel) {
- List<CommandType> result = new ArrayList<>();
+ public Collection<Typed> getCommandTypes(long deviceId, boolean textChannel) {
+ List<Typed> result = new ArrayList<>();
Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId);
if (lastPosition != null) {
BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol());
Collection<String> commands;
commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands();
for (String commandKey : commands) {
- result.add(new CommandType(commandKey));
+ result.add(new Typed(commandKey));
}
} else {
- result.add(new CommandType(Command.TYPE_CUSTOM));
+ result.add(new Typed(Command.TYPE_CUSTOM));
}
return result;
}
- public Collection<CommandType> getAllCommandTypes() {
- List<CommandType> result = new ArrayList<>();
+ public Collection<Typed> getAllCommandTypes() {
+ List<Typed> result = new ArrayList<>();
Field[] fields = Command.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) {
try {
- result.add(new CommandType(field.get(null).toString()));
+ result.add(new Typed(field.get(null).toString()));
} catch (IllegalArgumentException | IllegalAccessException error) {
Log.warning(error);
}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 261541b4d..e88ff7f0d 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -48,6 +48,7 @@ import org.traccar.model.Event;
import org.traccar.model.Geofence;
import org.traccar.model.Group;
import org.traccar.model.ManagedUser;
+import org.traccar.model.Notification;
import org.traccar.model.Permission;
import org.traccar.model.BaseModel;
import org.traccar.model.Calendar;
@@ -393,6 +394,8 @@ public class DataManager {
return Calendar.class;
case "command":
return Command.class;
+ case "notification":
+ return Notification.class;
default:
throw new ClassNotFoundException();
}
diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java
index 98cae3499..73041a23f 100644
--- a/src/org/traccar/database/NotificationManager.java
+++ b/src/org/traccar/database/NotificationManager.java
@@ -1,5 +1,6 @@
/*
* Copyright 2016 - 2017 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 - 2017 Andrey Kunitsyn (andrey@traccar.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,57 +19,70 @@ package org.traccar.database;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.SQLException;
-import java.util.Collection;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Event;
import org.traccar.model.Notification;
import org.traccar.model.Position;
+import org.traccar.model.Typed;
import org.traccar.notification.NotificationMail;
import org.traccar.notification.NotificationSms;
-public class NotificationManager {
-
- private final DataManager dataManager;
-
- private final Map<Long, Set<Notification>> userNotifications = new HashMap<>();
-
- private final ReadWriteLock notificationsLock = new ReentrantReadWriteLock();
+public class NotificationManager extends ExtendedObjectManager<Notification> {
public NotificationManager(DataManager dataManager) {
- this.dataManager = dataManager;
- refresh();
+ super(dataManager, Notification.class);
+ }
+
+ private Set<Long> getEffectiveNotifications(long userId, long deviceId) {
+ Set<Long> result = new HashSet<>();
+ Set<Long> deviceNotifications = getAllDeviceItems(deviceId);
+ for (long itemId : getUserItems(userId)) {
+ if (getById(itemId).getAlways() || deviceNotifications.contains(itemId)) {
+ result.add(itemId);
+ }
+ }
+ return result;
}
public void updateEvent(Event event, Position position) {
try {
- dataManager.addObject(event);
+ getDataManager().addObject(event);
} catch (SQLException error) {
Log.warning(error);
}
- Set<Long> users = Context.getPermissionsManager().getDeviceUsers(event.getDeviceId());
+ long deviceId = event.getDeviceId();
+ Set<Long> users = Context.getPermissionsManager().getDeviceUsers(deviceId);
for (long userId : users) {
if (event.getGeofenceId() == 0 || Context.getGeofenceManager() != null
&& Context.getGeofenceManager().checkItemPermission(userId, event.getGeofenceId())) {
- Notification notification = getUserNotificationByType(userId, event.getType());
- if (notification != null) {
- if (notification.getWeb()) {
- Context.getConnectionManager().updateEvent(userId, event);
- }
- if (notification.getMail()) {
- NotificationMail.sendMailAsync(userId, event, position);
+ boolean sentWeb = false;
+ boolean sentMail = false;
+ boolean sentSms = Context.getSmppManager() == null;
+ for (long notificationId : getEffectiveNotifications(userId, deviceId)) {
+ Notification notification = getById(notificationId);
+ if (getById(notificationId).getType().equals(event.getType())) {
+ if (!sentWeb && notification.getWeb()) {
+ Context.getConnectionManager().updateEvent(userId, event);
+ sentWeb = true;
+ }
+ if (!sentMail && notification.getMail()) {
+ NotificationMail.sendMailAsync(userId, event, position);
+ sentMail = true;
+ }
+ if (!sentSms && notification.getSms()) {
+ NotificationSms.sendSmsAsync(userId, event, position);
+ sentSms = true;
+ }
}
- if (notification.getSms()) {
- NotificationSms.sendSmsAsync(userId, event, position);
+ if (sentWeb && sentMail && sentSms) {
+ break;
}
}
}
@@ -84,135 +98,18 @@ public class NotificationManager {
}
}
- private Set<Notification> getUserNotificationsUnsafe(long userId) {
- if (!userNotifications.containsKey(userId)) {
- userNotifications.put(userId, new HashSet<Notification>());
- }
- return userNotifications.get(userId);
- }
-
- public Set<Notification> getUserNotifications(long userId) {
- notificationsLock.readLock().lock();
- try {
- return getUserNotificationsUnsafe(userId);
- } finally {
- notificationsLock.readLock().unlock();
- }
- }
-
- public final void refresh() {
- if (dataManager != null) {
- try {
- notificationsLock.writeLock().lock();
- try {
- userNotifications.clear();
- for (Notification notification : dataManager.getObjects(Notification.class)) {
- getUserNotificationsUnsafe(notification.getUserId()).add(notification);
- }
- } finally {
- notificationsLock.writeLock().unlock();
- }
- } catch (SQLException error) {
- Log.warning(error);
- }
- }
- }
-
- public Notification getUserNotificationByType(long userId, String type) {
- notificationsLock.readLock().lock();
- try {
- for (Notification notification : getUserNotificationsUnsafe(userId)) {
- if (notification.getType().equals(type)) {
- return notification;
- }
- }
- } finally {
- notificationsLock.readLock().unlock();
- }
- return null;
- }
-
- public void updateNotification(Notification notification) {
- Notification cachedNotification = getUserNotificationByType(notification.getUserId(), notification.getType());
- if (cachedNotification != null) {
- if (cachedNotification.getWeb() != notification.getWeb()
- || cachedNotification.getMail() != notification.getMail()
- || cachedNotification.getSms() != notification.getSms()) {
- if (!notification.getWeb() && !notification.getMail() && !notification.getSms()) {
- try {
- dataManager.removeObject(Notification.class, cachedNotification.getId());
- } catch (SQLException error) {
- Log.warning(error);
- }
- notificationsLock.writeLock().lock();
- try {
- getUserNotificationsUnsafe(notification.getUserId()).remove(cachedNotification);
- } finally {
- notificationsLock.writeLock().unlock();
- }
- } else {
- notificationsLock.writeLock().lock();
- try {
- cachedNotification.setWeb(notification.getWeb());
- cachedNotification.setMail(notification.getMail());
- cachedNotification.setSms(notification.getSms());
- cachedNotification.setAttributes(notification.getAttributes());
- } finally {
- notificationsLock.writeLock().unlock();
- }
- try {
- dataManager.updateObject(cachedNotification);
- } catch (SQLException error) {
- Log.warning(error);
- }
- }
- } else {
- notification.setId(cachedNotification.getId());
- }
- } else if (notification.getWeb() || notification.getMail() || notification.getSms()) {
- try {
- dataManager.addObject(notification);
- } catch (SQLException error) {
- Log.warning(error);
- }
- notificationsLock.writeLock().lock();
- try {
- getUserNotificationsUnsafe(notification.getUserId()).add(notification);
- } finally {
- notificationsLock.writeLock().unlock();
- }
- }
- }
-
- public Set<Notification> getAllNotifications() {
- Set<Notification> notifications = new HashSet<>();
- long id = 1;
+ public Set<Typed> getAllNotificationTypes() {
+ Set<Typed> types = new HashSet<>();
Field[] fields = Event.class.getDeclaredFields();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) {
try {
- Notification notification = new Notification();
- notification.setType(field.get(null).toString());
- notification.setId(id++);
- notifications.add(notification);
+ types.add(new Typed(field.get(null).toString()));
} catch (IllegalArgumentException | IllegalAccessException error) {
Log.warning(error);
}
}
}
- return notifications;
+ return types;
}
-
- public Collection<Notification> getAllUserNotifications(long userId) {
- Map<String, Notification> notifications = new HashMap<>();
- for (Notification notification : getAllNotifications()) {
- notification.setUserId(userId);
- notifications.put(notification.getType(), notification);
- }
- for (Notification notification : getUserNotifications(userId)) {
- notifications.put(notification.getType(), notification);
- }
- return notifications.values();
- }
-
}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 0d9c780a6..07b60ba58 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -26,6 +26,7 @@ import org.traccar.model.Driver;
import org.traccar.model.Geofence;
import org.traccar.model.Group;
import org.traccar.model.ManagedUser;
+import org.traccar.model.Notification;
import org.traccar.model.Permission;
import org.traccar.model.Server;
import org.traccar.model.User;
@@ -320,6 +321,8 @@ public class PermissionsManager {
manager = Context.getCalendarManager();
} else if (object.equals(Command.class)) {
manager = Context.getCommandsManager();
+ } else if (object.equals(Notification.class)) {
+ manager = Context.getNotificationManager();
} else {
throw new IllegalArgumentException("Unknown object type");
}
@@ -344,7 +347,7 @@ public class PermissionsManager {
Context.getAttributesManager().refreshUserItems();
Context.getCommandsManager().refreshUserItems();
if (Context.getNotificationManager() != null) {
- Context.getNotificationManager().refresh();
+ Context.getNotificationManager().refreshUserItems();
}
}
@@ -375,6 +378,9 @@ public class PermissionsManager {
Context.getCalendarManager().refreshUserItems();
} else if (permission.getPropertyClass().equals(Command.class)) {
Context.getCommandsManager().refreshUserItems();
+ } else if (permission.getPropertyClass().equals(Notification.class)
+ && Context.getNotificationManager() != null) {
+ Context.getNotificationManager().refreshUserItems();
}
} else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) {
if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) {
@@ -385,6 +391,9 @@ public class PermissionsManager {
Context.getAttributesManager().refreshExtendedPermissions();
} else if (permission.getPropertyClass().equals(Command.class)) {
Context.getCommandsManager().refreshExtendedPermissions();
+ } else if (permission.getPropertyClass().equals(Notification.class)
+ && Context.getNotificationManager() != null) {
+ Context.getNotificationManager().refreshExtendedPermissions();
}
}
}
diff --git a/src/org/traccar/model/Notification.java b/src/org/traccar/model/Notification.java
index e7bb69903..9d6034fff 100644
--- a/src/org/traccar/model/Notification.java
+++ b/src/org/traccar/model/Notification.java
@@ -17,14 +17,14 @@ package org.traccar.model;
public class Notification extends ExtendedModel {
- private long userId;
+ private boolean always;
- public long getUserId() {
- return userId;
+ public boolean getAlways() {
+ return always;
}
- public void setUserId(long userId) {
- this.userId = userId;
+ public void setAlways(boolean always) {
+ this.always = always;
}
private String type;
diff --git a/src/org/traccar/model/CommandType.java b/src/org/traccar/model/Typed.java
index 210316f71..313ec7bcd 100644
--- a/src/org/traccar/model/CommandType.java
+++ b/src/org/traccar/model/Typed.java
@@ -15,11 +15,11 @@
*/
package org.traccar.model;
-public class CommandType {
+public class Typed {
private String type;
- public CommandType(String type) {
+ public Typed(String type) {
this.type = type;
}