Add audit log details for telemetry deleted and telemetry updated types
This commit is contained in:
parent
9c44920fe7
commit
f1fb0cedae
@ -716,6 +716,9 @@ public abstract class BaseController {
|
|||||||
case TIMESERIES_UPDATED:
|
case TIMESERIES_UPDATED:
|
||||||
msgType = DataConstants.TIMESERIES_UPDATED;
|
msgType = DataConstants.TIMESERIES_UPDATED;
|
||||||
break;
|
break;
|
||||||
|
case TIMESERIES_DELETED:
|
||||||
|
msgType = DataConstants.TIMESERIES_DELETED;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (!StringUtils.isEmpty(msgType)) {
|
if (!StringUtils.isEmpty(msgType)) {
|
||||||
try {
|
try {
|
||||||
@ -774,6 +777,14 @@ public abstract class BaseController {
|
|||||||
} else if (actionType == ActionType.TIMESERIES_UPDATED) {
|
} else if (actionType == ActionType.TIMESERIES_UPDATED) {
|
||||||
List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);
|
List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);
|
||||||
addTimeseries(entityNode, timeseries);
|
addTimeseries(entityNode, timeseries);
|
||||||
|
} else if (actionType == ActionType.TIMESERIES_DELETED) {
|
||||||
|
List<String> keys = extractParameter(List.class, 0, additionalInfo);
|
||||||
|
if (keys != null) {
|
||||||
|
ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
|
||||||
|
keys.forEach(timeseriesArrayNode::add);
|
||||||
|
}
|
||||||
|
entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));
|
||||||
|
entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
|
TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
|
||||||
|
|||||||
@ -298,7 +298,6 @@ public class TelemetryController extends BaseController {
|
|||||||
deleteToTs = System.currentTimeMillis();
|
deleteToTs = System.currentTimeMillis();
|
||||||
} else {
|
} else {
|
||||||
if (startTs == null || endTs == null) {
|
if (startTs == null || endTs == null) {
|
||||||
deleteToTs = endTs;
|
|
||||||
return getImmediateDeferredResult("When deleteAllDataForKeys is false, start and end timestamp values shouldn't be empty", HttpStatus.BAD_REQUEST);
|
return getImmediateDeferredResult("When deleteAllDataForKeys is false, start and end timestamp values shouldn't be empty", HttpStatus.BAD_REQUEST);
|
||||||
} else {
|
} else {
|
||||||
deleteFromTs = startTs;
|
deleteFromTs = startTs;
|
||||||
@ -316,13 +315,13 @@ public class TelemetryController extends BaseController {
|
|||||||
Futures.addCallback(future, new FutureCallback<List<Void>>() {
|
Futures.addCallback(future, new FutureCallback<List<Void>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(@Nullable List<Void> tmp) {
|
public void onSuccess(@Nullable List<Void> tmp) {
|
||||||
logTimeseriesDeleted(user, entityId, keys, null);
|
logTimeseriesDeleted(user, entityId, keys, deleteFromTs, deleteToTs, null);
|
||||||
result.setResult(new ResponseEntity<>(HttpStatus.OK));
|
result.setResult(new ResponseEntity<>(HttpStatus.OK));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable t) {
|
public void onFailure(Throwable t) {
|
||||||
logTimeseriesDeleted(user, entityId, keys, t);
|
logTimeseriesDeleted(user, entityId, keys, deleteFromTs, deleteToTs, t);
|
||||||
result.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
|
result.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
|
||||||
}
|
}
|
||||||
}, executor);
|
}, executor);
|
||||||
@ -443,6 +442,7 @@ public class TelemetryController extends BaseController {
|
|||||||
if (entries.isEmpty()) {
|
if (entries.isEmpty()) {
|
||||||
return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST);
|
return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
SecurityUser user = getCurrentUser();
|
||||||
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_TELEMETRY, entityIdSrc, (result, tenantId, entityId) -> {
|
return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_TELEMETRY, entityIdSrc, (result, tenantId, entityId) -> {
|
||||||
long tenantTtl = ttl;
|
long tenantTtl = ttl;
|
||||||
if (!TenantId.SYS_TENANT_ID.equals(tenantId) && tenantTtl == 0) {
|
if (!TenantId.SYS_TENANT_ID.equals(tenantId) && tenantTtl == 0) {
|
||||||
@ -590,10 +590,10 @@ public class TelemetryController extends BaseController {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, Throwable e) {
|
private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, long startTs, long endTs, Throwable e) {
|
||||||
try {
|
try {
|
||||||
logEntityAction(user, (UUIDBased & EntityId) entityId, null, null, ActionType.TIMESERIES_DELETED, toException(e),
|
logEntityAction(user, (UUIDBased & EntityId) entityId, null, null, ActionType.TIMESERIES_DELETED, toException(e),
|
||||||
keys);
|
keys, startTs, endTs);
|
||||||
} catch (ThingsboardException te) {
|
} catch (ThingsboardException te) {
|
||||||
log.warn("Failed to log timeseries delete", te);
|
log.warn("Failed to log timeseries delete", te);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ public class DataConstants {
|
|||||||
public static final String ATTRIBUTES_UPDATED = "ATTRIBUTES_UPDATED";
|
public static final String ATTRIBUTES_UPDATED = "ATTRIBUTES_UPDATED";
|
||||||
public static final String ATTRIBUTES_DELETED = "ATTRIBUTES_DELETED";
|
public static final String ATTRIBUTES_DELETED = "ATTRIBUTES_DELETED";
|
||||||
public static final String TIMESERIES_UPDATED = "TIMESERIES_UPDATED";
|
public static final String TIMESERIES_UPDATED = "TIMESERIES_UPDATED";
|
||||||
|
public static final String TIMESERIES_DELETED = "TIMESERIES_DELETED";
|
||||||
public static final String ALARM_ACK = "ALARM_ACK";
|
public static final String ALARM_ACK = "ALARM_ACK";
|
||||||
public static final String ALARM_CLEAR = "ALARM_CLEAR";
|
public static final String ALARM_CLEAR = "ALARM_CLEAR";
|
||||||
public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT";
|
public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT";
|
||||||
|
|||||||
@ -24,8 +24,8 @@ public enum ActionType {
|
|||||||
UPDATED(false), // log entity
|
UPDATED(false), // log entity
|
||||||
ATTRIBUTES_UPDATED(false), // log attributes/values
|
ATTRIBUTES_UPDATED(false), // log attributes/values
|
||||||
ATTRIBUTES_DELETED(false), // log attributes
|
ATTRIBUTES_DELETED(false), // log attributes
|
||||||
TIMESERIES_DELETED(false), // log timeseries
|
|
||||||
TIMESERIES_UPDATED(false), // log timeseries update
|
TIMESERIES_UPDATED(false), // log timeseries update
|
||||||
|
TIMESERIES_DELETED(false), // log timeseries
|
||||||
RPC_CALL(false), // log method and params
|
RPC_CALL(false), // log method and params
|
||||||
CREDENTIALS_UPDATED(false), // log new credentials
|
CREDENTIALS_UPDATED(false), // log new credentials
|
||||||
ASSIGNED_TO_CUSTOMER(false), // log customer name
|
ASSIGNED_TO_CUSTOMER(false), // log customer name
|
||||||
|
|||||||
@ -39,21 +39,23 @@ import org.thingsboard.server.common.data.id.EntityId;
|
|||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.id.UserId;
|
import org.thingsboard.server.common.data.id.UserId;
|
||||||
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
|
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
|
||||||
|
import org.thingsboard.server.common.data.kv.TsKvEntry;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.TimePageLink;
|
import org.thingsboard.server.common.data.page.TimePageLink;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
|
||||||
import org.thingsboard.server.common.data.security.DeviceCredentials;
|
import org.thingsboard.server.common.data.security.DeviceCredentials;
|
||||||
import org.thingsboard.server.dao.audit.sink.AuditLogSink;
|
import org.thingsboard.server.dao.audit.sink.AuditLogSink;
|
||||||
|
import org.thingsboard.server.dao.device.provision.ProvisionRequest;
|
||||||
import org.thingsboard.server.dao.entity.EntityService;
|
import org.thingsboard.server.dao.entity.EntityService;
|
||||||
import org.thingsboard.server.dao.exception.DataValidationException;
|
import org.thingsboard.server.dao.exception.DataValidationException;
|
||||||
import org.thingsboard.server.dao.device.provision.ProvisionRequest;
|
|
||||||
import org.thingsboard.server.dao.service.DataValidator;
|
import org.thingsboard.server.dao.service.DataValidator;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.thingsboard.server.dao.service.Validator.validateEntityId;
|
import static org.thingsboard.server.dao.service.Validator.validateEntityId;
|
||||||
import static org.thingsboard.server.dao.service.Validator.validateId;
|
import static org.thingsboard.server.dao.service.Validator.validateId;
|
||||||
@ -265,6 +267,32 @@ public class AuditLogServiceImpl implements AuditLogService {
|
|||||||
actionData.set("provisionRequest", objectMapper.valueToTree(request));
|
actionData.set("provisionRequest", objectMapper.valueToTree(request));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TIMESERIES_UPDATED:
|
||||||
|
actionData.put("entityId", entityId.toString());
|
||||||
|
List<TsKvEntry> updatedTimeseries = extractParameter(List.class, 0, additionalInfo);
|
||||||
|
if (updatedTimeseries != null) {
|
||||||
|
ArrayNode result = actionData.putArray("timeseries");
|
||||||
|
updatedTimeseries.stream()
|
||||||
|
.collect(Collectors.groupingBy(TsKvEntry::getTs))
|
||||||
|
.forEach((k, v) -> {
|
||||||
|
ObjectNode element = objectMapper.createObjectNode();
|
||||||
|
element.put("ts", k);
|
||||||
|
ObjectNode values = element.putObject("values");
|
||||||
|
v.forEach(kvEntry -> values.put(kvEntry.getKey(), kvEntry.getValueAsString()));
|
||||||
|
result.add(element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TIMESERIES_DELETED:
|
||||||
|
actionData.put("entityId", entityId.toString());
|
||||||
|
List<String> timeseriesKeys = extractParameter(List.class, 0, additionalInfo);
|
||||||
|
if (timeseriesKeys != null) {
|
||||||
|
ArrayNode timeseriesArrayNode = actionData.putArray("timeseries");
|
||||||
|
timeseriesKeys.forEach(timeseriesArrayNode::add);
|
||||||
|
}
|
||||||
|
actionData.put("startTs", extractParameter(Long.class, 1, additionalInfo));
|
||||||
|
actionData.put("endTs", extractParameter(Long.class, 2, additionalInfo));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return actionData;
|
return actionData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,7 +35,8 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
|
|||||||
configClazz = EmptyNodeConfiguration.class,
|
configClazz = EmptyNodeConfiguration.class,
|
||||||
relationTypes = {"Post attributes", "Post telemetry", "RPC Request from Device", "RPC Request to Device", "Activity Event", "Inactivity Event",
|
relationTypes = {"Post attributes", "Post telemetry", "RPC Request from Device", "RPC Request to Device", "Activity Event", "Inactivity Event",
|
||||||
"Connect Event", "Disconnect Event", "Entity Created", "Entity Updated", "Entity Deleted", "Entity Assigned",
|
"Connect Event", "Disconnect Event", "Entity Created", "Entity Updated", "Entity Deleted", "Entity Assigned",
|
||||||
"Entity Unassigned", "Attributes Updated", "Attributes Deleted", "Alarm Acknowledged", "Alarm Cleared", "Other", "Entity Assigned From Tenant", "Entity Assigned To Tenant", "Timeseries Updated"},
|
"Entity Unassigned", "Attributes Updated", "Attributes Deleted", "Alarm Acknowledged", "Alarm Cleared", "Other", "Entity Assigned From Tenant", "Entity Assigned To Tenant",
|
||||||
|
"Timeseries Updated", "Timeseries Deleted"},
|
||||||
nodeDescription = "Route incoming messages by Message Type",
|
nodeDescription = "Route incoming messages by Message Type",
|
||||||
nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.",
|
nodeDetails = "Sends messages with message types <b>\"Post attributes\", \"Post telemetry\", \"RPC Request\"</b> etc. via corresponding chain, otherwise <b>Other</b> chain is used.",
|
||||||
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
uiResources = {"static/rulenode/rulenode-core-config.js"},
|
||||||
@ -91,7 +92,9 @@ public class TbMsgTypeSwitchNode implements TbNode {
|
|||||||
} else if (msg.getType().equals(DataConstants.ENTITY_ASSIGNED_TO_TENANT)) {
|
} else if (msg.getType().equals(DataConstants.ENTITY_ASSIGNED_TO_TENANT)) {
|
||||||
relationType = "Entity Assigned To Tenant";
|
relationType = "Entity Assigned To Tenant";
|
||||||
} else if (msg.getType().equals(DataConstants.TIMESERIES_UPDATED)) {
|
} else if (msg.getType().equals(DataConstants.TIMESERIES_UPDATED)) {
|
||||||
relationType = "Timeseries updated";
|
relationType = "Timeseries Updated";
|
||||||
|
} else if (msg.getType().equals(DataConstants.TIMESERIES_DELETED)) {
|
||||||
|
relationType = "Timeseries Deleted";
|
||||||
} else {
|
} else {
|
||||||
relationType = "Other";
|
relationType = "Other";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,7 +53,9 @@ export enum ActionType {
|
|||||||
ASSIGNED_FROM_TENANT = 'ASSIGNED_FROM_TENANT',
|
ASSIGNED_FROM_TENANT = 'ASSIGNED_FROM_TENANT',
|
||||||
ASSIGNED_TO_TENANT = 'ASSIGNED_TO_TENANT',
|
ASSIGNED_TO_TENANT = 'ASSIGNED_TO_TENANT',
|
||||||
PROVISION_SUCCESS = 'PROVISION_SUCCESS',
|
PROVISION_SUCCESS = 'PROVISION_SUCCESS',
|
||||||
PROVISION_FAILURE = 'PROVISION_FAILURE'
|
PROVISION_FAILURE = 'PROVISION_FAILURE',
|
||||||
|
TIMESERIES_UPDATED = 'TIMESERIES_UPDATED',
|
||||||
|
TIMESERIES_DELETED = 'TIMESERIES_DELETED'
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ActionStatus {
|
export enum ActionStatus {
|
||||||
@ -87,7 +89,9 @@ export const actionTypeTranslations = new Map<ActionType, string>(
|
|||||||
[ActionType.ASSIGNED_FROM_TENANT, 'audit-log.type-assigned-from-tenant'],
|
[ActionType.ASSIGNED_FROM_TENANT, 'audit-log.type-assigned-from-tenant'],
|
||||||
[ActionType.ASSIGNED_TO_TENANT, 'audit-log.type-assigned-to-tenant'],
|
[ActionType.ASSIGNED_TO_TENANT, 'audit-log.type-assigned-to-tenant'],
|
||||||
[ActionType.PROVISION_SUCCESS, 'audit-log.type-provision-success'],
|
[ActionType.PROVISION_SUCCESS, 'audit-log.type-provision-success'],
|
||||||
[ActionType.PROVISION_FAILURE, 'audit-log.type-provision-failure']
|
[ActionType.PROVISION_FAILURE, 'audit-log.type-provision-failure'],
|
||||||
|
[ActionType.TIMESERIES_UPDATED, 'audit-log.type-timeseries-updated'],
|
||||||
|
[ActionType.TIMESERIES_DELETED, 'audit-log.type-timeseries-deleted']
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -527,7 +527,9 @@
|
|||||||
"type-assigned-from-tenant": "Assigned from Tenant",
|
"type-assigned-from-tenant": "Assigned from Tenant",
|
||||||
"type-assigned-to-tenant": "Assigned to Tenant",
|
"type-assigned-to-tenant": "Assigned to Tenant",
|
||||||
"type-provision-success": "Device provisioned",
|
"type-provision-success": "Device provisioned",
|
||||||
"type-provision-failure": "Device provisioning was failed"
|
"type-provision-failure": "Device provisioning was failed",
|
||||||
|
"type-timeseries-updated": "Telemetry updated",
|
||||||
|
"type-timeseries-deleted": "Telemetry deleted"
|
||||||
},
|
},
|
||||||
"confirm-on-exit": {
|
"confirm-on-exit": {
|
||||||
"message": "You have unsaved changes. Are you sure you want to leave this page?",
|
"message": "You have unsaved changes. Are you sure you want to leave this page?",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user