Commit f1fb0cedae51eb129e24b69a8b2ad44e2b57e463

Authored by Viacheslav Kukhtyn
1 parent 9c44920f

Add audit log details for telemetry deleted and telemetry updated types

... ... @@ -716,6 +716,9 @@ public abstract class BaseController {
716 716 case TIMESERIES_UPDATED:
717 717 msgType = DataConstants.TIMESERIES_UPDATED;
718 718 break;
  719 + case TIMESERIES_DELETED:
  720 + msgType = DataConstants.TIMESERIES_DELETED;
  721 + break;
719 722 }
720 723 if (!StringUtils.isEmpty(msgType)) {
721 724 try {
... ... @@ -774,6 +777,14 @@ public abstract class BaseController {
774 777 } else if (actionType == ActionType.TIMESERIES_UPDATED) {
775 778 List<TsKvEntry> timeseries = extractParameter(List.class, 0, additionalInfo);
776 779 addTimeseries(entityNode, timeseries);
  780 + } else if (actionType == ActionType.TIMESERIES_DELETED) {
  781 + List<String> keys = extractParameter(List.class, 0, additionalInfo);
  782 + if (keys != null) {
  783 + ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
  784 + keys.forEach(timeseriesArrayNode::add);
  785 + }
  786 + entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo));
  787 + entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo));
777 788 }
778 789 }
779 790 TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode));
... ...
... ... @@ -298,7 +298,6 @@ public class TelemetryController extends BaseController {
298 298 deleteToTs = System.currentTimeMillis();
299 299 } else {
300 300 if (startTs == null || endTs == null) {
301   - deleteToTs = endTs;
302 301 return getImmediateDeferredResult("When deleteAllDataForKeys is false, start and end timestamp values shouldn't be empty", HttpStatus.BAD_REQUEST);
303 302 } else {
304 303 deleteFromTs = startTs;
... ... @@ -316,13 +315,13 @@ public class TelemetryController extends BaseController {
316 315 Futures.addCallback(future, new FutureCallback<List<Void>>() {
317 316 @Override
318 317 public void onSuccess(@Nullable List<Void> tmp) {
319   - logTimeseriesDeleted(user, entityId, keys, null);
  318 + logTimeseriesDeleted(user, entityId, keys, deleteFromTs, deleteToTs, null);
320 319 result.setResult(new ResponseEntity<>(HttpStatus.OK));
321 320 }
322 321
323 322 @Override
324 323 public void onFailure(Throwable t) {
325   - logTimeseriesDeleted(user, entityId, keys, t);
  324 + logTimeseriesDeleted(user, entityId, keys, deleteFromTs, deleteToTs, t);
326 325 result.setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
327 326 }
328 327 }, executor);
... ... @@ -443,6 +442,7 @@ public class TelemetryController extends BaseController {
443 442 if (entries.isEmpty()) {
444 443 return getImmediateDeferredResult("No timeseries data found in request body!", HttpStatus.BAD_REQUEST);
445 444 }
  445 + SecurityUser user = getCurrentUser();
446 446 return accessValidator.validateEntityAndCallback(getCurrentUser(), Operation.WRITE_TELEMETRY, entityIdSrc, (result, tenantId, entityId) -> {
447 447 long tenantTtl = ttl;
448 448 if (!TenantId.SYS_TENANT_ID.equals(tenantId) && tenantTtl == 0) {
... ... @@ -590,10 +590,10 @@ public class TelemetryController extends BaseController {
590 590 };
591 591 }
592 592
593   - private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, Throwable e) {
  593 + private void logTimeseriesDeleted(SecurityUser user, EntityId entityId, List<String> keys, long startTs, long endTs, Throwable e) {
594 594 try {
595 595 logEntityAction(user, (UUIDBased & EntityId) entityId, null, null, ActionType.TIMESERIES_DELETED, toException(e),
596   - keys);
  596 + keys, startTs, endTs);
597 597 } catch (ThingsboardException te) {
598 598 log.warn("Failed to log timeseries delete", te);
599 599 }
... ...
... ... @@ -60,6 +60,7 @@ public class DataConstants {
60 60 public static final String ATTRIBUTES_UPDATED = "ATTRIBUTES_UPDATED";
61 61 public static final String ATTRIBUTES_DELETED = "ATTRIBUTES_DELETED";
62 62 public static final String TIMESERIES_UPDATED = "TIMESERIES_UPDATED";
  63 + public static final String TIMESERIES_DELETED = "TIMESERIES_DELETED";
63 64 public static final String ALARM_ACK = "ALARM_ACK";
64 65 public static final String ALARM_CLEAR = "ALARM_CLEAR";
65 66 public static final String ENTITY_ASSIGNED_FROM_TENANT = "ENTITY_ASSIGNED_FROM_TENANT";
... ...
... ... @@ -24,8 +24,8 @@ public enum ActionType {
24 24 UPDATED(false), // log entity
25 25 ATTRIBUTES_UPDATED(false), // log attributes/values
26 26 ATTRIBUTES_DELETED(false), // log attributes
27   - TIMESERIES_DELETED(false), // log timeseries
28 27 TIMESERIES_UPDATED(false), // log timeseries update
  28 + TIMESERIES_DELETED(false), // log timeseries
29 29 RPC_CALL(false), // log method and params
30 30 CREDENTIALS_UPDATED(false), // log new credentials
31 31 ASSIGNED_TO_CUSTOMER(false), // log customer name
... ...
... ... @@ -39,21 +39,23 @@ import org.thingsboard.server.common.data.id.EntityId;
39 39 import org.thingsboard.server.common.data.id.TenantId;
40 40 import org.thingsboard.server.common.data.id.UserId;
41 41 import org.thingsboard.server.common.data.kv.AttributeKvEntry;
  42 +import org.thingsboard.server.common.data.kv.TsKvEntry;
42 43 import org.thingsboard.server.common.data.page.PageData;
43 44 import org.thingsboard.server.common.data.page.TimePageLink;
44 45 import org.thingsboard.server.common.data.relation.EntityRelation;
45 46 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
46 47 import org.thingsboard.server.common.data.security.DeviceCredentials;
47 48 import org.thingsboard.server.dao.audit.sink.AuditLogSink;
  49 +import org.thingsboard.server.dao.device.provision.ProvisionRequest;
48 50 import org.thingsboard.server.dao.entity.EntityService;
49 51 import org.thingsboard.server.dao.exception.DataValidationException;
50   -import org.thingsboard.server.dao.device.provision.ProvisionRequest;
51 52 import org.thingsboard.server.dao.service.DataValidator;
52 53
53 54 import java.io.PrintWriter;
54 55 import java.io.StringWriter;
55 56 import java.util.List;
56 57 import java.util.UUID;
  58 +import java.util.stream.Collectors;
57 59
58 60 import static org.thingsboard.server.dao.service.Validator.validateEntityId;
59 61 import static org.thingsboard.server.dao.service.Validator.validateId;
... ... @@ -265,6 +267,32 @@ public class AuditLogServiceImpl implements AuditLogService {
265 267 actionData.set("provisionRequest", objectMapper.valueToTree(request));
266 268 }
267 269 break;
  270 + case TIMESERIES_UPDATED:
  271 + actionData.put("entityId", entityId.toString());
  272 + List<TsKvEntry> updatedTimeseries = extractParameter(List.class, 0, additionalInfo);
  273 + if (updatedTimeseries != null) {
  274 + ArrayNode result = actionData.putArray("timeseries");
  275 + updatedTimeseries.stream()
  276 + .collect(Collectors.groupingBy(TsKvEntry::getTs))
  277 + .forEach((k, v) -> {
  278 + ObjectNode element = objectMapper.createObjectNode();
  279 + element.put("ts", k);
  280 + ObjectNode values = element.putObject("values");
  281 + v.forEach(kvEntry -> values.put(kvEntry.getKey(), kvEntry.getValueAsString()));
  282 + result.add(element);
  283 + });
  284 + }
  285 + break;
  286 + case TIMESERIES_DELETED:
  287 + actionData.put("entityId", entityId.toString());
  288 + List<String> timeseriesKeys = extractParameter(List.class, 0, additionalInfo);
  289 + if (timeseriesKeys != null) {
  290 + ArrayNode timeseriesArrayNode = actionData.putArray("timeseries");
  291 + timeseriesKeys.forEach(timeseriesArrayNode::add);
  292 + }
  293 + actionData.put("startTs", extractParameter(Long.class, 1, additionalInfo));
  294 + actionData.put("endTs", extractParameter(Long.class, 2, additionalInfo));
  295 + break;
268 296 }
269 297 return actionData;
270 298 }
... ...
... ... @@ -35,7 +35,8 @@ import org.thingsboard.server.common.msg.session.SessionMsgType;
35 35 configClazz = EmptyNodeConfiguration.class,
36 36 relationTypes = {"Post attributes", "Post telemetry", "RPC Request from Device", "RPC Request to Device", "Activity Event", "Inactivity Event",
37 37 "Connect Event", "Disconnect Event", "Entity Created", "Entity Updated", "Entity Deleted", "Entity Assigned",
38   - "Entity Unassigned", "Attributes Updated", "Attributes Deleted", "Alarm Acknowledged", "Alarm Cleared", "Other", "Entity Assigned From Tenant", "Entity Assigned To Tenant", "Timeseries Updated"},
  38 + "Entity Unassigned", "Attributes Updated", "Attributes Deleted", "Alarm Acknowledged", "Alarm Cleared", "Other", "Entity Assigned From Tenant", "Entity Assigned To Tenant",
  39 + "Timeseries Updated", "Timeseries Deleted"},
39 40 nodeDescription = "Route incoming messages by Message Type",
40 41 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.",
41 42 uiResources = {"static/rulenode/rulenode-core-config.js"},
... ... @@ -91,7 +92,9 @@ public class TbMsgTypeSwitchNode implements TbNode {
91 92 } else if (msg.getType().equals(DataConstants.ENTITY_ASSIGNED_TO_TENANT)) {
92 93 relationType = "Entity Assigned To Tenant";
93 94 } else if (msg.getType().equals(DataConstants.TIMESERIES_UPDATED)) {
94   - relationType = "Timeseries updated";
  95 + relationType = "Timeseries Updated";
  96 + } else if (msg.getType().equals(DataConstants.TIMESERIES_DELETED)) {
  97 + relationType = "Timeseries Deleted";
95 98 } else {
96 99 relationType = "Other";
97 100 }
... ...
... ... @@ -53,7 +53,9 @@ export enum ActionType {
53 53 ASSIGNED_FROM_TENANT = 'ASSIGNED_FROM_TENANT',
54 54 ASSIGNED_TO_TENANT = 'ASSIGNED_TO_TENANT',
55 55 PROVISION_SUCCESS = 'PROVISION_SUCCESS',
56   - PROVISION_FAILURE = 'PROVISION_FAILURE'
  56 + PROVISION_FAILURE = 'PROVISION_FAILURE',
  57 + TIMESERIES_UPDATED = 'TIMESERIES_UPDATED',
  58 + TIMESERIES_DELETED = 'TIMESERIES_DELETED'
57 59 }
58 60
59 61 export enum ActionStatus {
... ... @@ -87,7 +89,9 @@ export const actionTypeTranslations = new Map<ActionType, string>(
87 89 [ActionType.ASSIGNED_FROM_TENANT, 'audit-log.type-assigned-from-tenant'],
88 90 [ActionType.ASSIGNED_TO_TENANT, 'audit-log.type-assigned-to-tenant'],
89 91 [ActionType.PROVISION_SUCCESS, 'audit-log.type-provision-success'],
90   - [ActionType.PROVISION_FAILURE, 'audit-log.type-provision-failure']
  92 + [ActionType.PROVISION_FAILURE, 'audit-log.type-provision-failure'],
  93 + [ActionType.TIMESERIES_UPDATED, 'audit-log.type-timeseries-updated'],
  94 + [ActionType.TIMESERIES_DELETED, 'audit-log.type-timeseries-deleted']
91 95 ]
92 96 );
93 97
... ...
... ... @@ -527,7 +527,9 @@
527 527 "type-assigned-from-tenant": "Assigned from Tenant",
528 528 "type-assigned-to-tenant": "Assigned to Tenant",
529 529 "type-provision-success": "Device provisioned",
530   - "type-provision-failure": "Device provisioning was failed"
  530 + "type-provision-failure": "Device provisioning was failed",
  531 + "type-timeseries-updated": "Telemetry updated",
  532 + "type-timeseries-deleted": "Telemetry deleted"
531 533 },
532 534 "confirm-on-exit": {
533 535 "message": "You have unsaved changes. Are you sure you want to leave this page?",
... ...