aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar')
-rw-r--r--src/org/traccar/api/resource/GroupResource.java10
-rw-r--r--src/org/traccar/database/DataManager.java94
-rw-r--r--src/org/traccar/database/DeviceManager.java140
-rw-r--r--src/org/traccar/database/GeofenceManager.java4
-rw-r--r--src/org/traccar/database/PermissionsManager.java3
5 files changed, 134 insertions, 117 deletions
diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java
index 957f39ebe..eec28e325 100644
--- a/src/org/traccar/api/resource/GroupResource.java
+++ b/src/org/traccar/api/resource/GroupResource.java
@@ -43,20 +43,20 @@ public class GroupResource extends BaseResource {
@QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException {
if (all) {
Context.getPermissionsManager().checkAdmin(getUserId());
- return Context.getDataManager().getAllGroups();
+ return Context.getDeviceManager().getAllGroups();
} else {
if (userId == 0) {
userId = getUserId();
}
Context.getPermissionsManager().checkUser(getUserId(), userId);
- return Context.getDataManager().getGroups(userId);
+ return Context.getDeviceManager().getGroups(userId);
}
}
@POST
public Response add(Group entity) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
- Context.getDataManager().addGroup(entity);
+ Context.getDeviceManager().addGroup(entity);
Context.getDataManager().linkGroup(getUserId(), entity.getId());
Context.getPermissionsManager().refresh();
if (Context.getGeofenceManager() != null) {
@@ -70,7 +70,7 @@ public class GroupResource extends BaseResource {
public Response update(@PathParam("id") long id, Group entity) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
Context.getPermissionsManager().checkGroup(getUserId(), id);
- Context.getDataManager().updateGroup(entity);
+ Context.getDeviceManager().updateGroup(entity);
if (Context.getGeofenceManager() != null) {
Context.getGeofenceManager().refresh();
}
@@ -82,7 +82,7 @@ public class GroupResource extends BaseResource {
public Response remove(@PathParam("id") long id) throws SQLException {
Context.getPermissionsManager().checkReadonly(getUserId());
Context.getPermissionsManager().checkGroup(getUserId(), id);
- Context.getDataManager().removeGroup(id);
+ Context.getDeviceManager().removeGroup(id);
Context.getPermissionsManager().refresh();
if (Context.getGeofenceManager() != null) {
Context.getGeofenceManager().refresh();
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 0aecaf2e7..be77a3d36 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -20,16 +20,9 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.SQLException;
-import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.naming.InitialContext;
import javax.sql.DataSource;
@@ -43,7 +36,6 @@ import liquibase.resource.FileSystemResourceAccessor;
import liquibase.resource.ResourceAccessor;
import org.traccar.Config;
-import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Device;
import org.traccar.model.DevicePermission;
@@ -64,25 +56,15 @@ import com.zaxxer.hikari.HikariDataSource;
public class DataManager {
- public static final long DEFAULT_REFRESH_DELAY = 300;
-
private final Config config;
private DataSource dataSource;
- private final long dataRefreshDelay;
-
- private final ReadWriteLock groupsLock = new ReentrantReadWriteLock();
- private final Map<Long, Group> groupsById = new HashMap<>();
- private long groupsLastUpdate;
-
public DataManager(Config config) throws Exception {
this.config = config;
initDatabase();
initDatabaseSchema();
-
- dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000;
}
public DataSource getDataSource() {
@@ -131,54 +113,6 @@ public class DataManager {
}
}
- private void updateGroupCache(boolean force) throws SQLException {
- boolean needWrite;
- groupsLock.readLock().lock();
- try {
- needWrite = force || System.currentTimeMillis() - groupsLastUpdate > dataRefreshDelay;
- } finally {
- groupsLock.readLock().unlock();
- }
-
- if (needWrite) {
- groupsLock.writeLock().lock();
- try {
- if (force || System.currentTimeMillis() - groupsLastUpdate > dataRefreshDelay) {
- groupsById.clear();
- for (Group group : getAllGroups()) {
- groupsById.put(group.getId(), group);
- }
- groupsLastUpdate = System.currentTimeMillis();
- }
- } finally {
- groupsLock.writeLock().unlock();
- }
- }
- }
-
- public Group getGroupById(long id) {
- boolean forceUpdate;
- groupsLock.readLock().lock();
- try {
- forceUpdate = !groupsById.containsKey(id);
- } finally {
- groupsLock.readLock().unlock();
- }
-
- try {
- updateGroupCache(forceUpdate);
- } catch (SQLException e) {
- Log.warning(e);
- }
-
- groupsLock.readLock().lock();
- try {
- return groupsById.get(id);
- } finally {
- groupsLock.readLock().unlock();
- }
- }
-
private String getQuery(String key) {
String query = config.getString(key);
if (query == null) {
@@ -311,44 +245,16 @@ public class DataManager {
.executeQuery(Group.class);
}
- public Collection<Group> getGroups(long userId) throws SQLException {
- Collection<Group> groups = new ArrayList<>();
- for (long id : Context.getPermissionsManager().getGroupPermissions(userId)) {
- groups.add(getGroupById(id));
- }
- return groups;
- }
-
- private void checkGroupCycles(Group group) {
- groupsLock.readLock().lock();
- try {
- Set<Long> groups = new HashSet<>();
- while (group != null) {
- if (groups.contains(group.getId())) {
- throw new IllegalArgumentException("Cycle in group hierarchy");
- }
- groups.add(group.getId());
- group = groupsById.get(group.getGroupId());
- }
- } finally {
- groupsLock.readLock().unlock();
- }
- }
-
public void addGroup(Group group) throws SQLException {
- checkGroupCycles(group);
group.setId(QueryBuilder.create(dataSource, getQuery("database.insertGroup"), true)
.setObject(group)
.executeUpdate());
- updateGroupCache(true);
}
public void updateGroup(Group group) throws SQLException {
- checkGroupCycles(group);
QueryBuilder.create(dataSource, getQuery("database.updateGroup"))
.setObject(group)
.executeUpdate();
- updateGroupCache(true);
}
public void removeGroup(long groupId) throws SQLException {
diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java
index 173e68062..43d83d078 100644
--- a/src/org/traccar/database/DeviceManager.java
+++ b/src/org/traccar/database/DeviceManager.java
@@ -19,9 +19,11 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -30,10 +32,13 @@ import org.traccar.Config;
import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Device;
+import org.traccar.model.Group;
import org.traccar.model.Position;
public class DeviceManager implements IdentityManager {
+ public static final long DEFAULT_REFRESH_DELAY = 300;
+
private final Config config;
private final DataManager dataManager;
private final long dataRefreshDelay;
@@ -43,14 +48,20 @@ public class DeviceManager implements IdentityManager {
private final Map<String, Device> devicesByUniqueId = new HashMap<>();
private long devicesLastUpdate;
+ private final ReadWriteLock groupsLock = new ReentrantReadWriteLock();
+ private final Map<Long, Group> groupsById = new HashMap<>();
+ private long groupsLastUpdate;
+
private final Map<Long, Position> positions = new ConcurrentHashMap<>();
public DeviceManager(DataManager dataManager) {
this.dataManager = dataManager;
this.config = Context.getConfig();
- dataRefreshDelay = config.getLong("database.refreshDelay", DataManager.DEFAULT_REFRESH_DELAY) * 1000;
+ dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000;
if (dataManager != null) {
try {
+ updateGroupCache(true);
+ updateDeviceCache(true);
for (Position position : dataManager.getLatestPositions()) {
positions.put(position.getDeviceId(), position);
}
@@ -96,20 +107,6 @@ public class DeviceManager implements IdentityManager {
@Override
public Device getDeviceById(long id) {
- boolean forceUpdate;
- devicesLock.readLock().lock();
- try {
- forceUpdate = !devicesById.containsKey(id);
- } finally {
- devicesLock.readLock().unlock();
- }
-
- try {
- updateDeviceCache(forceUpdate);
- } catch (SQLException e) {
- Log.warning(e);
- }
-
devicesLock.readLock().lock();
try {
return devicesById.get(id);
@@ -273,4 +270,117 @@ public class DeviceManager implements IdentityManager {
return result;
}
+
+ private void updateGroupCache(boolean force) throws SQLException {
+ boolean needWrite;
+ groupsLock.readLock().lock();
+ try {
+ needWrite = force || System.currentTimeMillis() - groupsLastUpdate > dataRefreshDelay;
+ } finally {
+ groupsLock.readLock().unlock();
+ }
+
+ if (needWrite) {
+ groupsLock.writeLock().lock();
+ try {
+ if (force || System.currentTimeMillis() - groupsLastUpdate > dataRefreshDelay) {
+ groupsById.clear();
+ for (Group group : dataManager.getAllGroups()) {
+ groupsById.put(group.getId(), group);
+ }
+ groupsLastUpdate = System.currentTimeMillis();
+ }
+ } finally {
+ groupsLock.writeLock().unlock();
+ }
+ }
+ }
+
+ public Group getGroupById(long id) {
+ groupsLock.readLock().lock();
+ try {
+ return groupsById.get(id);
+ } finally {
+ groupsLock.readLock().unlock();
+ }
+ }
+
+ public Collection<Group> getAllGroups() {
+ boolean forceUpdate;
+ groupsLock.readLock().lock();
+ try {
+ forceUpdate = groupsById.isEmpty();
+ } finally {
+ groupsLock.readLock().unlock();
+ }
+
+ try {
+ updateGroupCache(forceUpdate);
+ } catch (SQLException e) {
+ Log.warning(e);
+ }
+
+ groupsLock.readLock().lock();
+ try {
+ return groupsById.values();
+ } finally {
+ groupsLock.readLock().unlock();
+ }
+ }
+
+ public Collection<Group> getGroups(long userId) throws SQLException {
+ Collection<Group> groups = new ArrayList<>();
+ for (long id : Context.getPermissionsManager().getGroupPermissions(userId)) {
+ groups.add(getGroupById(id));
+ }
+ return groups;
+ }
+
+ private void checkGroupCycles(Group group) {
+ groupsLock.readLock().lock();
+ try {
+ Set<Long> groups = new HashSet<>();
+ while (group != null) {
+ if (groups.contains(group.getId())) {
+ throw new IllegalArgumentException("Cycle in group hierarchy");
+ }
+ groups.add(group.getId());
+ group = groupsById.get(group.getGroupId());
+ }
+ } finally {
+ groupsLock.readLock().unlock();
+ }
+ }
+
+ public void addGroup(Group group) throws SQLException {
+ checkGroupCycles(group);
+ dataManager.addGroup(group);
+ groupsLock.writeLock().lock();
+ try {
+ groupsById.put(group.getId(), group);
+ } finally {
+ groupsLock.writeLock().unlock();
+ }
+ }
+
+ public void updateGroup(Group group) throws SQLException {
+ checkGroupCycles(group);
+ dataManager.updateGroup(group);
+ groupsLock.writeLock().lock();
+ try {
+ groupsById.put(group.getId(), group);
+ } finally {
+ groupsLock.writeLock().unlock();
+ }
+ }
+
+ public void removeGroup(long groupId) throws SQLException {
+ dataManager.removeGroup(groupId);
+ groupsLock.writeLock().lock();
+ try {
+ groupsById.remove(groupId);
+ } finally {
+ groupsLock.writeLock().unlock();
+ }
+ }
}
diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java
index 930008082..74dff70f4 100644
--- a/src/org/traccar/database/GeofenceManager.java
+++ b/src/org/traccar/database/GeofenceManager.java
@@ -188,8 +188,8 @@ public class GeofenceManager {
while (groupId != 0) {
getDeviceGeofences(deviceGeofencesWithGroups,
device.getId()).addAll(getGroupGeofences(groupId));
- if (dataManager.getGroupById(groupId) != null) {
- groupId = dataManager.getGroupById(groupId).getGroupId();
+ if (Context.getDeviceManager().getGroupById(groupId) != null) {
+ groupId = Context.getDeviceManager().getGroupById(groupId).getGroupId();
} else {
groupId = 0;
}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 5a15375b4..d786dcc4e 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -78,7 +78,8 @@ public class PermissionsManager {
users.put(user.getId(), user);
}
- GroupTree groupTree = new GroupTree(dataManager.getAllGroups(), Context.getDeviceManager().getAllDevices());
+ GroupTree groupTree = new GroupTree(Context.getDeviceManager().getAllGroups(),
+ Context.getDeviceManager().getAllDevices());
for (GroupPermission permission : dataManager.getGroupPermissions()) {
Set<Long> userGroupPermissions = getGroupPermissions(permission.getUserId());
Set<Long> userDevicePermissions = getDevicePermissions(permission.getUserId());