aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Tananaev <anton@traccar.org>2022-07-13 17:31:52 -0700
committerAnton Tananaev <anton@traccar.org>2022-07-13 17:31:52 -0700
commita8e38b74e5fc6789676bf35a9b92594a230e3ad8 (patch)
treeeed89969aecd7c9652f8640742530c96a4fc40b3
parent33733f835e88a62c4a5259ab330723b88037adf1 (diff)
downloadtrackermap-server-a8e38b74e5fc6789676bf35a9b92594a230e3ad8.tar.gz
trackermap-server-a8e38b74e5fc6789676bf35a9b92594a230e3ad8.tar.bz2
trackermap-server-a8e38b74e5fc6789676bf35a9b92594a230e3ad8.zip
Avoid broadcast loops (fix #4894)
-rw-r--r--src/main/java/org/traccar/api/BaseObjectResource.java6
-rw-r--r--src/main/java/org/traccar/api/resource/PermissionsResource.java2
-rw-r--r--src/main/java/org/traccar/api/resource/ServerResource.java2
-rw-r--r--src/main/java/org/traccar/broadcast/BroadcastInterface.java3
-rw-r--r--src/main/java/org/traccar/broadcast/MulticastBroadcastService.java5
-rw-r--r--src/main/java/org/traccar/session/ConnectionManager.java1
-rw-r--r--src/main/java/org/traccar/session/cache/CacheManager.java15
7 files changed, 23 insertions, 11 deletions
diff --git a/src/main/java/org/traccar/api/BaseObjectResource.java b/src/main/java/org/traccar/api/BaseObjectResource.java
index d10843917..2a3bbe239 100644
--- a/src/main/java/org/traccar/api/BaseObjectResource.java
+++ b/src/main/java/org/traccar/api/BaseObjectResource.java
@@ -71,8 +71,8 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
entity.setId(storage.addObject(entity, new Request(new Columns.Exclude("id"))));
LogAction.create(getUserId(), entity);
storage.addPermission(new Permission(User.class, getUserId(), baseClass, entity.getId()));
- cacheManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId());
- connectionManager.invalidatePermission(User.class, getUserId(), baseClass, entity.getId());
+ cacheManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId());
+ connectionManager.invalidatePermission(true, User.class, getUserId(), baseClass, entity.getId());
LogAction.link(getUserId(), User.class, getUserId(), baseClass, entity.getId());
return Response.ok(entity).build();
@@ -98,7 +98,7 @@ public abstract class BaseObjectResource<T extends BaseModel> extends BaseResour
storage.updateObject(entity, new Request(
new Columns.Exclude("id"),
new Condition.Equals("id", "id")));
- cacheManager.updateOrInvalidate(entity);
+ cacheManager.updateOrInvalidate(true, entity);
LogAction.edit(getUserId(), entity);
return Response.ok(entity).build();
diff --git a/src/main/java/org/traccar/api/resource/PermissionsResource.java b/src/main/java/org/traccar/api/resource/PermissionsResource.java
index 44fc897ac..d35cb98bb 100644
--- a/src/main/java/org/traccar/api/resource/PermissionsResource.java
+++ b/src/main/java/org/traccar/api/resource/PermissionsResource.java
@@ -72,6 +72,7 @@ public class PermissionsResource extends BaseResource {
checkPermission(permission);
storage.addPermission(permission);
cacheManager.invalidatePermission(
+ true,
permission.getOwnerClass(), permission.getOwnerId(),
permission.getPropertyClass(), permission.getPropertyId());
LogAction.link(getUserId(),
@@ -96,6 +97,7 @@ public class PermissionsResource extends BaseResource {
checkPermission(permission);
storage.removePermission(permission);
cacheManager.invalidatePermission(
+ true,
permission.getOwnerClass(), permission.getOwnerId(),
permission.getPropertyClass(), permission.getPropertyId());
LogAction.unlink(getUserId(),
diff --git a/src/main/java/org/traccar/api/resource/ServerResource.java b/src/main/java/org/traccar/api/resource/ServerResource.java
index 3e6792f5b..4fc76a0d7 100644
--- a/src/main/java/org/traccar/api/resource/ServerResource.java
+++ b/src/main/java/org/traccar/api/resource/ServerResource.java
@@ -77,7 +77,7 @@ public class ServerResource extends BaseResource {
storage.updateObject(entity, new Request(
new Columns.Exclude("id"),
new Condition.Equals("id", "id")));
- cacheManager.updateOrInvalidate(entity);
+ cacheManager.updateOrInvalidate(true, entity);
LogAction.edit(getUserId(), entity);
return Response.ok(entity).build();
}
diff --git a/src/main/java/org/traccar/broadcast/BroadcastInterface.java b/src/main/java/org/traccar/broadcast/BroadcastInterface.java
index 69e610dc6..dddba68b6 100644
--- a/src/main/java/org/traccar/broadcast/BroadcastInterface.java
+++ b/src/main/java/org/traccar/broadcast/BroadcastInterface.java
@@ -31,10 +31,11 @@ public interface BroadcastInterface {
default void updateEvent(boolean local, long userId, Event event) {
}
- default void invalidateObject(Class<? extends BaseModel> clazz, long id) {
+ default void invalidateObject(boolean local, Class<? extends BaseModel> clazz, long id) {
}
default void invalidatePermission(
+ boolean local,
Class<? extends BaseModel> clazz1, long id1,
Class<? extends BaseModel> clazz2, long id2) {
}
diff --git a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java
index be24989dd..3eafe07d3 100644
--- a/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java
+++ b/src/main/java/org/traccar/broadcast/MulticastBroadcastService.java
@@ -98,7 +98,7 @@ public class MulticastBroadcastService implements BroadcastService {
}
@Override
- public void invalidateObject(Class<? extends BaseModel> clazz, long id) {
+ public void invalidateObject(boolean local, Class<? extends BaseModel> clazz, long id) {
BroadcastMessage message = new BroadcastMessage();
message.setChanges(Map.of(Permission.getKey(clazz), id));
sendMessage(message);
@@ -106,6 +106,7 @@ public class MulticastBroadcastService implements BroadcastService {
@Override
public void invalidatePermission(
+ boolean local,
Class<? extends BaseModel> clazz1, long id1,
Class<? extends BaseModel> clazz2, long id2) {
BroadcastMessage message = new BroadcastMessage();
@@ -137,10 +138,12 @@ public class MulticastBroadcastService implements BroadcastService {
if (iterator.hasNext()) {
var second = iterator.next();
listeners.forEach(listener -> listener.invalidatePermission(
+ false,
Permission.getKeyClass(first.getKey()), first.getValue(),
Permission.getKeyClass(second.getKey()), second.getValue()));
} else {
listeners.forEach(listener -> listener.invalidateObject(
+ false,
Permission.getKeyClass(first.getKey()), first.getValue()));
}
}
diff --git a/src/main/java/org/traccar/session/ConnectionManager.java b/src/main/java/org/traccar/session/ConnectionManager.java
index 62fdd833b..9888cca2b 100644
--- a/src/main/java/org/traccar/session/ConnectionManager.java
+++ b/src/main/java/org/traccar/session/ConnectionManager.java
@@ -364,6 +364,7 @@ public class ConnectionManager implements BroadcastInterface {
@Override
public synchronized void invalidatePermission(
+ boolean local,
Class<? extends BaseModel> clazz1, long id1,
Class<? extends BaseModel> clazz2, long id2) {
if (clazz1.equals(User.class) && clazz2.equals(Device.class)) {
diff --git a/src/main/java/org/traccar/session/cache/CacheManager.java b/src/main/java/org/traccar/session/cache/CacheManager.java
index 4e99161dd..58eb95327 100644
--- a/src/main/java/org/traccar/session/cache/CacheManager.java
+++ b/src/main/java/org/traccar/session/cache/CacheManager.java
@@ -188,12 +188,12 @@ public class CacheManager implements BroadcastInterface {
}
@Override
- public void invalidateObject(Class<? extends BaseModel> clazz, long id) {
+ public void invalidateObject(boolean local, Class<? extends BaseModel> clazz, long id) {
try {
var object = storage.getObject(clazz, new Request(
new Columns.All(), new Condition.Equals("id", "id", id)));
if (object != null) {
- updateOrInvalidate(object);
+ updateOrInvalidate(local, object);
} else {
invalidate(clazz, id);
}
@@ -202,8 +202,10 @@ public class CacheManager implements BroadcastInterface {
}
}
- public <T extends BaseModel> void updateOrInvalidate(T object) throws StorageException {
- broadcastService.invalidateObject(object.getClass(), object.getId());
+ public <T extends BaseModel> void updateOrInvalidate(boolean local, T object) throws StorageException {
+ if (local) {
+ broadcastService.invalidateObject(true, object.getClass(), object.getId());
+ }
boolean invalidate = false;
var before = getObject(object.getClass(), object.getId());
@@ -232,9 +234,12 @@ public class CacheManager implements BroadcastInterface {
@Override
public void invalidatePermission(
+ boolean local,
Class<? extends BaseModel> clazz1, long id1,
Class<? extends BaseModel> clazz2, long id2) {
- broadcastService.invalidatePermission(clazz1, id1, clazz2, id2);
+ if (local) {
+ broadcastService.invalidatePermission(true, clazz1, id1, clazz2, id2);
+ }
try {
invalidate(new CacheKey(clazz1, id1), new CacheKey(clazz2, id2));