diff options
Diffstat (limited to 'src')
12 files changed, 48 insertions, 215 deletions
diff --git a/src/main/java/org/traccar/Context.java b/src/main/java/org/traccar/Context.java index cbbc73d76..9e8e3c521 100644 --- a/src/main/java/org/traccar/Context.java +++ b/src/main/java/org/traccar/Context.java @@ -19,14 +19,13 @@ import org.traccar.config.Config; import org.traccar.database.BaseObjectManager; import org.traccar.database.DataManager; import org.traccar.database.DeviceManager; -import org.traccar.database.GroupsManager; import org.traccar.database.IdentityManager; import org.traccar.database.PermissionsManager; import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Device; -import org.traccar.model.Group; import org.traccar.session.ConnectionManager; +import org.traccar.session.cache.CacheManager; import org.traccar.storage.Storage; public final class Context { @@ -46,12 +45,6 @@ public final class Context { return identityManager; } - private static GroupsManager groupsManager; - - public static GroupsManager getGroupsManager() { - return groupsManager; - } - private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -75,9 +68,9 @@ public final class Context { throw e; } - groupsManager = new GroupsManager(Main.getInjector().getInstance(DataManager.class)); deviceManager = new DeviceManager( config, + Main.getInjector().getInstance(CacheManager.class), Main.getInjector().getInstance(DataManager.class), Main.getInjector().getInstance(ConnectionManager.class)); @@ -92,8 +85,6 @@ public final class Context { public static <T extends BaseModel> BaseObjectManager<T> getManager(Class<T> clazz) { if (clazz.equals(Device.class)) { return (BaseObjectManager<T>) deviceManager; - } else if (clazz.equals(Group.class)) { - return (BaseObjectManager<T>) groupsManager; } return null; } diff --git a/src/main/java/org/traccar/WebDataHandler.java b/src/main/java/org/traccar/WebDataHandler.java index 2c0aa0f8e..db99ecaf8 100644 --- a/src/main/java/org/traccar/WebDataHandler.java +++ b/src/main/java/org/traccar/WebDataHandler.java @@ -31,6 +31,7 @@ import org.traccar.helper.Checksum; import org.traccar.model.Device; import org.traccar.model.Position; import org.traccar.model.Group; +import org.traccar.session.cache.CacheManager; import javax.inject.Inject; import javax.ws.rs.core.HttpHeaders; @@ -60,6 +61,7 @@ public class WebDataHandler extends BaseDataHandler { private static final String KEY_POSITION = "position"; private static final String KEY_DEVICE = "device"; + private final CacheManager cacheManager; private final IdentityManager identityManager; private final ObjectMapper objectMapper; private final Client client; @@ -78,8 +80,10 @@ public class WebDataHandler extends BaseDataHandler { @Inject public WebDataHandler( - Config config, IdentityManager identityManager, ObjectMapper objectMapper, Client client) { + Config config, CacheManager cacheManager, IdentityManager identityManager, + ObjectMapper objectMapper, Client client) { + this.cacheManager = cacheManager; this.identityManager = identityManager; this.objectMapper = objectMapper; this.client = client; @@ -171,7 +175,7 @@ public class WebDataHandler extends BaseDataHandler { if (request.contains("{group}")) { String deviceGroupName = ""; if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { deviceGroupName = group.getName(); } diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java index f8545a5d7..78aa12dbe 100644 --- a/src/main/java/org/traccar/api/BaseObjectResource.java +++ b/src/main/java/org/traccar/api/BaseObjectResource.java @@ -18,7 +18,6 @@ package org.traccar.api; import org.traccar.Context; import org.traccar.database.BaseObjectManager; -import org.traccar.database.ExtendedObjectManager; import org.traccar.helper.LogAction; import org.traccar.model.BaseModel; import org.traccar.model.Device; @@ -92,10 +91,16 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour public Response update(T entity) throws StorageException { permissionsService.checkEdit(getUserId(), entity, false); permissionsService.checkPermission(baseClass, getUserId(), entity.getId()); + if (entity instanceof User) { User before = storage.getObject(User.class, new Request( new Columns.All(), new Condition.Equals("id", "id", entity.getId()))); permissionsService.checkUserUpdate(getUserId(), before, (User) entity); + } else if (entity instanceof Group) { + Group group = (Group) entity; + if (group.getId() == group.getGroupId()) { + throw new IllegalArgumentException("Cycle in group hierarchy"); + } } BaseObjectManager<T> manager = Context.getManager(baseClass); @@ -125,9 +130,6 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour BaseObjectManager<T> manager = Context.getManager(baseClass); if (manager != null) { manager.removeItem(id); - if (manager instanceof ExtendedObjectManager) { - ((ExtendedObjectManager<T>) manager).refreshExtendedPermissions(); - } } else { storage.removeObject(baseClass, new Request(new Condition.Equals("id", "id", id))); } @@ -137,7 +139,6 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour if (baseClass.equals(Group.class) || baseClass.equals(Device.class) || baseClass.equals(User.class)) { if (baseClass.equals(Group.class)) { - Context.getGroupsManager().refreshItems(); Context.getDeviceManager().updateDeviceCache(true); } Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); diff --git a/src/main/java/org/traccar/database/DeviceManager.java b/src/main/java/org/traccar/database/DeviceManager.java index 9ba486988..29c17c41f 100644 --- a/src/main/java/org/traccar/database/DeviceManager.java +++ b/src/main/java/org/traccar/database/DeviceManager.java @@ -46,6 +46,7 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity private static final Logger LOGGER = LoggerFactory.getLogger(DeviceManager.class); private final Config config; + private final CacheManager cacheManager; private final ConnectionManager connectionManager; private final long dataRefreshDelay; @@ -56,9 +57,11 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity private final Map<Long, DeviceState> deviceStates = new ConcurrentHashMap<>(); - public DeviceManager(Config config, DataManager dataManager, ConnectionManager connectionManager) { + public DeviceManager( + Config config, CacheManager cacheManager, DataManager dataManager, ConnectionManager connectionManager) { super(dataManager, Device.class); this.config = config; + this.cacheManager = cacheManager; this.connectionManager = connectionManager; try { writeLock(); @@ -351,8 +354,8 @@ public class DeviceManager extends BaseObjectManager<Device> implements Identity result = device.getAttributes().get(attributeName); if (result == null) { long groupId = device.getGroupId(); - while (groupId != 0) { - Group group = Context.getGroupsManager().getById(groupId); + while (groupId > 0) { + Group group = cacheManager.getObject(Group.class, device.getGroupId()); if (group != null) { result = group.getAttributes().get(attributeName); if (result != null) { diff --git a/src/main/java/org/traccar/database/ExtendedObjectManager.java b/src/main/java/org/traccar/database/ExtendedObjectManager.java deleted file mode 100644 index fe0ebb96e..000000000 --- a/src/main/java/org/traccar/database/ExtendedObjectManager.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2017 - 2020 Anton Tananaev (anton@traccar.org) - * Copyright 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.database; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.traccar.Context; -import org.traccar.model.Device; -import org.traccar.model.Group; -import org.traccar.model.Permission; -import org.traccar.model.BaseModel; -import org.traccar.storage.StorageException; - -public abstract class ExtendedObjectManager<T extends BaseModel> extends SimpleObjectManager<T> { - - private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedObjectManager.class); - - private final Map<Long, Set<Long>> deviceItems = new ConcurrentHashMap<>(); - private final Map<Long, Set<Long>> deviceItemsWithGroups = new ConcurrentHashMap<>(); - private final Map<Long, Set<Long>> groupItems = new ConcurrentHashMap<>(); - - protected ExtendedObjectManager(DataManager dataManager, Class<T> baseClass) { - super(dataManager, baseClass); - refreshExtendedPermissions(); - } - - public Set<Long> getAllDeviceItems(long deviceId) { - try { - readLock(); - Set<Long> result = deviceItemsWithGroups.get(deviceId); - if (result != null) { - return new HashSet<>(result); - } else { - return new HashSet<>(); - } - } finally { - readUnlock(); - } - } - - @Override - public void removeItem(long itemId) throws StorageException { - super.removeItem(itemId); - refreshExtendedPermissions(); - } - - public void refreshExtendedPermissions() { - if (getDataManager() != null) { - try { - Collection<Permission> databaseGroupPermissions = - getDataManager().getPermissions(Group.class, getBaseClass()); - - Collection<Permission> databaseDevicePermissions = - getDataManager().getPermissions(Device.class, getBaseClass()); - - writeLock(); - - groupItems.clear(); - deviceItems.clear(); - deviceItemsWithGroups.clear(); - - for (Permission groupPermission : databaseGroupPermissions) { - groupItems - .computeIfAbsent(groupPermission.getOwnerId(), key -> new HashSet<>()) - .add(groupPermission.getPropertyId()); - } - - for (Permission devicePermission : databaseDevicePermissions) { - deviceItems - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - deviceItemsWithGroups - .computeIfAbsent(devicePermission.getOwnerId(), key -> new HashSet<>()) - .add(devicePermission.getPropertyId()); - } - - for (Device device : getDataManager().getObjects(Device.class)) { - long groupId = device.getGroupId(); - while (groupId > 0) { - deviceItemsWithGroups - .computeIfAbsent(device.getId(), key -> new HashSet<>()) - .addAll(groupItems.getOrDefault(groupId, new HashSet<>())); - Group group = Context.getGroupsManager().getById(groupId); - groupId = group != null ? group.getGroupId() : 0; - } - } - - } catch (StorageException | ClassNotFoundException error) { - LOGGER.warn("Refresh permissions error", error); - } finally { - writeUnlock(); - } - } - } -} diff --git a/src/main/java/org/traccar/database/GroupsManager.java b/src/main/java/org/traccar/database/GroupsManager.java deleted file mode 100644 index 4df848042..000000000 --- a/src/main/java/org/traccar/database/GroupsManager.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2017 - 2022 Anton Tananaev (anton@traccar.org) - * Copyright 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.database; - -import java.util.HashSet; -import java.util.Set; - -import org.traccar.model.Group; -import org.traccar.storage.StorageException; - -public class GroupsManager extends BaseObjectManager<Group> { - - public GroupsManager(DataManager dataManager) { - super(dataManager, Group.class); - } - - private void checkGroupCycles(Group group) { - 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 = getById(group.getGroupId()); - } - } - - @Override - public Set<Long> getAllItems() { - Set<Long> result = super.getAllItems(); - if (result.isEmpty()) { - refreshItems(); - result = super.getAllItems(); - } - return result; - } - - @Override - protected void addNewItem(Group group) { - checkGroupCycles(group); - super.addNewItem(group); - } - - @Override - public void updateItem(Group group) throws StorageException { - checkGroupCycles(group); - super.updateItem(group); - } - -} diff --git a/src/main/java/org/traccar/database/PermissionsManager.java b/src/main/java/org/traccar/database/PermissionsManager.java index 833480eea..595e236fa 100644 --- a/src/main/java/org/traccar/database/PermissionsManager.java +++ b/src/main/java/org/traccar/database/PermissionsManager.java @@ -162,9 +162,8 @@ public class PermissionsManager { groupPermissions.clear(); devicePermissions.clear(); try { - GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Context.getGroupsManager().getAllItems()), - Context.getDeviceManager().getAllDevices()); + var groups = dataManager.getObjects(Group.class); + GroupTree groupTree = new GroupTree(groups, Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set<Long> userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); Set<Long> userDevicePermissions = getDevicePermissions(groupPermission.getOwnerId()); @@ -182,9 +181,9 @@ public class PermissionsManager { } groupDevices.clear(); - for (long groupId : Context.getGroupsManager().getAllItems()) { - for (Device device : groupTree.getDevices(groupId)) { - getGroupDevices(groupId).add(device.getId()); + for (var group : groups) { + for (Device device : groupTree.getDevices(group.getId())) { + getGroupDevices(group.getId()).add(device.getId()); } } diff --git a/src/main/java/org/traccar/reports/EventsReportProvider.java b/src/main/java/org/traccar/reports/EventsReportProvider.java index 5148695a9..b1f7149a2 100644 --- a/src/main/java/org/traccar/reports/EventsReportProvider.java +++ b/src/main/java/org/traccar/reports/EventsReportProvider.java @@ -134,8 +134,9 @@ public class EventsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/RouteReportProvider.java b/src/main/java/org/traccar/reports/RouteReportProvider.java index b1a806960..903dfe369 100644 --- a/src/main/java/org/traccar/reports/RouteReportProvider.java +++ b/src/main/java/org/traccar/reports/RouteReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.common.ReportUtils; import org.traccar.reports.model.DeviceReportSection; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -77,8 +80,9 @@ public class RouteReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/StopsReportProvider.java b/src/main/java/org/traccar/reports/StopsReportProvider.java index a6a9a94cc..b9d36eb97 100644 --- a/src/main/java/org/traccar/reports/StopsReportProvider.java +++ b/src/main/java/org/traccar/reports/StopsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.StopReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class StopsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/main/java/org/traccar/reports/TripsReportProvider.java b/src/main/java/org/traccar/reports/TripsReportProvider.java index bff559664..97cfccf74 100644 --- a/src/main/java/org/traccar/reports/TripsReportProvider.java +++ b/src/main/java/org/traccar/reports/TripsReportProvider.java @@ -28,6 +28,9 @@ import org.traccar.reports.model.DeviceReportSection; import org.traccar.reports.model.TripReportItem; import org.traccar.storage.Storage; import org.traccar.storage.StorageException; +import org.traccar.storage.query.Columns; +import org.traccar.storage.query.Condition; +import org.traccar.storage.query.Request; import javax.inject.Inject; import java.io.File; @@ -85,8 +88,9 @@ public class TripsReportProvider { Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); - if (device.getGroupId() != 0) { - Group group = Context.getGroupsManager().getById(device.getGroupId()); + if (device.getGroupId() > 0) { + Group group = storage.getObject(Group.class, new Request( + new Columns.All(), new Condition.Equals("id", "id", device.getGroupId()))); if (group != null) { deviceTrips.setGroupName(group.getName()); } diff --git a/src/test/java/org/traccar/WebDataHandlerTest.java b/src/test/java/org/traccar/WebDataHandlerTest.java index aaec9f530..ff9c80ce6 100644 --- a/src/test/java/org/traccar/WebDataHandlerTest.java +++ b/src/test/java/org/traccar/WebDataHandlerTest.java @@ -6,6 +6,7 @@ import org.traccar.config.Keys; import org.traccar.database.IdentityManager; import org.traccar.model.Device; import org.traccar.model.Position; +import org.traccar.session.cache.CacheManager; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyLong; @@ -30,7 +31,7 @@ public class WebDataHandlerTest extends ProtocolTest { var identityManager = mock(IdentityManager.class); when(identityManager.getById(anyLong())).thenReturn(device); - WebDataHandler handler = new WebDataHandler(config, identityManager, null, null); + WebDataHandler handler = new WebDataHandler(config, mock(CacheManager.class), identityManager, null, null); assertEquals( "http://localhost/?fixTime=1451610123000&gprmc=$GPRMC,010203.000,A,2000.0000,N,03000.0000,E,0.00,0.00,010116,,*05&name=test", |