Showing
11 changed files
with
93 additions
and
30 deletions
... | ... | @@ -26,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestParam; |
26 | 26 | import org.springframework.web.bind.annotation.ResponseBody; |
27 | 27 | import org.springframework.web.bind.annotation.ResponseStatus; |
28 | 28 | import org.springframework.web.bind.annotation.RestController; |
29 | +import org.thingsboard.server.common.data.EntityType; | |
29 | 30 | import org.thingsboard.server.common.data.alarm.Alarm; |
30 | 31 | import org.thingsboard.server.common.data.alarm.AlarmId; |
31 | 32 | import org.thingsboard.server.common.data.alarm.AlarmInfo; |
... | ... | @@ -33,6 +34,7 @@ import org.thingsboard.server.common.data.alarm.AlarmQuery; |
33 | 34 | import org.thingsboard.server.common.data.alarm.AlarmSearchStatus; |
34 | 35 | import org.thingsboard.server.common.data.alarm.AlarmSeverity; |
35 | 36 | import org.thingsboard.server.common.data.alarm.AlarmStatus; |
37 | +import org.thingsboard.server.common.data.audit.ActionType; | |
36 | 38 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
37 | 39 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
38 | 40 | import org.thingsboard.server.common.data.id.EntityId; |
... | ... | @@ -53,7 +55,6 @@ public class AlarmController extends BaseController { |
53 | 55 | checkParameter(ALARM_ID, strAlarmId); |
54 | 56 | try { |
55 | 57 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
56 | - | |
57 | 58 | return checkAlarmId(alarmId); |
58 | 59 | } catch (Exception e) { |
59 | 60 | throw handleException(e); |
... | ... | @@ -79,8 +80,14 @@ public class AlarmController extends BaseController { |
79 | 80 | public Alarm saveAlarm(@RequestBody Alarm alarm) throws ThingsboardException { |
80 | 81 | try { |
81 | 82 | alarm.setTenantId(getCurrentUser().getTenantId()); |
82 | - return checkNotNull(alarmService.createOrUpdateAlarm(alarm)); | |
83 | + Alarm savedAlarm = checkNotNull(alarmService.createOrUpdateAlarm(alarm)); | |
84 | + logEntityAction(savedAlarm.getId(), savedAlarm, | |
85 | + getCurrentUser().getCustomerId(), | |
86 | + savedAlarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, null); | |
87 | + return savedAlarm; | |
83 | 88 | } catch (Exception e) { |
89 | + logEntityAction(emptyId(EntityType.ASSET), alarm, | |
90 | + null, alarm.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e); | |
84 | 91 | throw handleException(e); |
85 | 92 | } |
86 | 93 | } |
... | ... | @@ -92,8 +99,9 @@ public class AlarmController extends BaseController { |
92 | 99 | checkParameter(ALARM_ID, strAlarmId); |
93 | 100 | try { |
94 | 101 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
95 | - checkAlarmId(alarmId); | |
102 | + Alarm alarm = checkAlarmId(alarmId); | |
96 | 103 | alarmService.ackAlarm(alarmId, System.currentTimeMillis()).get(); |
104 | + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_ACK, null); | |
97 | 105 | } catch (Exception e) { |
98 | 106 | throw handleException(e); |
99 | 107 | } |
... | ... | @@ -106,8 +114,9 @@ public class AlarmController extends BaseController { |
106 | 114 | checkParameter(ALARM_ID, strAlarmId); |
107 | 115 | try { |
108 | 116 | AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); |
109 | - checkAlarmId(alarmId); | |
117 | + Alarm alarm = checkAlarmId(alarmId); | |
110 | 118 | alarmService.clearAlarm(alarmId, null, System.currentTimeMillis()).get(); |
119 | + logEntityAction(alarmId, alarm, getCurrentUser().getCustomerId(), ActionType.ALARM_CLEAR, null); | |
111 | 120 | } catch (Exception e) { |
112 | 121 | throw handleException(e); |
113 | 122 | } | ... | ... |
... | ... | @@ -529,18 +529,16 @@ public abstract class BaseController { |
529 | 529 | return baseUrl; |
530 | 530 | } |
531 | 531 | |
532 | - protected <I extends UUIDBased & EntityId> I emptyId(EntityType entityType) { | |
532 | + protected <I extends EntityId> I emptyId(EntityType entityType) { | |
533 | 533 | return (I)EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID); |
534 | 534 | } |
535 | 535 | |
536 | - protected <E extends BaseData<I> & HasName, | |
537 | - I extends UUIDBased & EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId, | |
536 | + protected <E extends HasName, I extends EntityId> void logEntityAction(I entityId, E entity, CustomerId customerId, | |
538 | 537 | ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException { |
539 | 538 | logEntityAction(getCurrentUser(), entityId, entity, customerId, actionType, e, additionalInfo); |
540 | 539 | } |
541 | 540 | |
542 | - protected <E extends BaseData<I> & HasName, | |
543 | - I extends UUIDBased & EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId, | |
541 | + protected <E extends HasName, I extends EntityId> void logEntityAction(User user, I entityId, E entity, CustomerId customerId, | |
544 | 542 | ActionType actionType, Exception e, Object... additionalInfo) throws ThingsboardException { |
545 | 543 | if (customerId == null || customerId.isNullUid()) { |
546 | 544 | customerId = user.getCustomerId(); |
... | ... | @@ -556,8 +554,7 @@ public abstract class BaseController { |
556 | 554 | return error != null ? (Exception.class.isInstance(error) ? (Exception) error : new Exception(error)) : null; |
557 | 555 | } |
558 | 556 | |
559 | - private <E extends BaseData<I> & HasName, | |
560 | - I extends UUIDBased & EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId, | |
557 | + private <E extends HasName, I extends EntityId> void pushEntityActionToRuleEngine(I entityId, E entity, User user, CustomerId customerId, | |
561 | 558 | ActionType actionType, Object... additionalInfo) { |
562 | 559 | String msgType = null; |
563 | 560 | switch (actionType) { | ... | ... |
... | ... | @@ -24,10 +24,13 @@ import org.springframework.web.bind.annotation.RequestParam; |
24 | 24 | import org.springframework.web.bind.annotation.ResponseBody; |
25 | 25 | import org.springframework.web.bind.annotation.ResponseStatus; |
26 | 26 | import org.springframework.web.bind.annotation.RestController; |
27 | +import org.thingsboard.server.common.data.alarm.Alarm; | |
28 | +import org.thingsboard.server.common.data.audit.ActionType; | |
27 | 29 | import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; |
28 | 30 | import org.thingsboard.server.common.data.exception.ThingsboardException; |
29 | 31 | import org.thingsboard.server.common.data.id.EntityId; |
30 | 32 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
33 | +import org.thingsboard.server.common.data.id.UUIDBased; | |
31 | 34 | import org.thingsboard.server.common.data.relation.EntityRelation; |
32 | 35 | import org.thingsboard.server.common.data.relation.EntityRelationInfo; |
33 | 36 | import org.thingsboard.server.common.data.relation.EntityRelationsQuery; |
... | ... | @@ -58,7 +61,15 @@ public class EntityRelationController extends BaseController { |
58 | 61 | relation.setTypeGroup(RelationTypeGroup.COMMON); |
59 | 62 | } |
60 | 63 | relationService.saveRelation(relation); |
64 | + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), | |
65 | + ActionType.RELATION_ADD_OR_UPDATE, null, relation); | |
66 | + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), | |
67 | + ActionType.RELATION_ADD_OR_UPDATE, null, relation); | |
61 | 68 | } catch (Exception e) { |
69 | + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), | |
70 | + ActionType.RELATION_ADD_OR_UPDATE, e, relation); | |
71 | + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), | |
72 | + ActionType.RELATION_ADD_OR_UPDATE, e, relation); | |
62 | 73 | throw handleException(e); |
63 | 74 | } |
64 | 75 | } |
... | ... | @@ -81,12 +92,21 @@ public class EntityRelationController extends BaseController { |
81 | 92 | checkEntityId(fromId); |
82 | 93 | checkEntityId(toId); |
83 | 94 | RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); |
95 | + EntityRelation relation = new EntityRelation(fromId, toId, strRelationType, relationTypeGroup); | |
84 | 96 | try { |
85 | 97 | Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup); |
86 | 98 | if (!found) { |
87 | 99 | throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND); |
88 | 100 | } |
101 | + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), | |
102 | + ActionType.RELATION_DELETED, null, relation); | |
103 | + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), | |
104 | + ActionType.RELATION_DELETED, null, relation); | |
89 | 105 | } catch (Exception e) { |
106 | + logEntityAction(relation.getFrom(), null, getCurrentUser().getCustomerId(), | |
107 | + ActionType.RELATION_DELETED, e, relation); | |
108 | + logEntityAction(relation.getTo(), null, getCurrentUser().getCustomerId(), | |
109 | + ActionType.RELATION_DELETED, e, relation); | |
90 | 110 | throw handleException(e); |
91 | 111 | } |
92 | 112 | } |
... | ... | @@ -102,7 +122,9 @@ public class EntityRelationController extends BaseController { |
102 | 122 | checkEntityId(entityId); |
103 | 123 | try { |
104 | 124 | relationService.deleteEntityRelations(entityId); |
125 | + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, null); | |
105 | 126 | } catch (Exception e) { |
127 | + logEntityAction(entityId, null, getCurrentUser().getCustomerId(), ActionType.RELATIONS_DELETED, e); | |
106 | 128 | throw handleException(e); |
107 | 129 | } |
108 | 130 | } |
... | ... | @@ -210,8 +232,8 @@ public class EntityRelationController extends BaseController { |
210 | 232 | @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) |
211 | 233 | @ResponseBody |
212 | 234 | public List<EntityRelationInfo> findInfoByTo(@RequestParam(TO_ID) String strToId, |
213 | - @RequestParam(TO_TYPE) String strToType, | |
214 | - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { | |
235 | + @RequestParam(TO_TYPE) String strToType, | |
236 | + @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { | |
215 | 237 | checkParameter(TO_ID, strToId); |
216 | 238 | checkParameter(TO_TYPE, strToType); |
217 | 239 | EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); |
... | ... | @@ -276,10 +298,11 @@ public class EntityRelationController extends BaseController { |
276 | 298 | |
277 | 299 | private RelationTypeGroup parseRelationTypeGroup(String strRelationTypeGroup, RelationTypeGroup defaultValue) { |
278 | 300 | RelationTypeGroup result = defaultValue; |
279 | - if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) { | |
301 | + if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length() > 0) { | |
280 | 302 | try { |
281 | 303 | result = RelationTypeGroup.valueOf(strRelationTypeGroup); |
282 | - } catch (IllegalArgumentException e) { } | |
304 | + } catch (IllegalArgumentException e) { | |
305 | + } | |
283 | 306 | } |
284 | 307 | return result; |
285 | 308 | } | ... | ... |
... | ... | @@ -385,6 +385,7 @@ audit_log: |
385 | 385 | "customer": "${AUDIT_LOG_MASK_CUSTOMER:W}" |
386 | 386 | "user": "${AUDIT_LOG_MASK_USER:W}" |
387 | 387 | "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}" |
388 | + "alarm": "${AUDIT_LOG_MASK_ALARM:W}" | |
388 | 389 | sink: |
389 | 390 | # Type of external sink. possible options: none, elasticsearch |
390 | 391 | type: "${AUDIT_LOG_SINK_TYPE:none}" | ... | ... |
... | ... | @@ -31,7 +31,12 @@ public enum ActionType { |
31 | 31 | ACTIVATED(false), // log string id |
32 | 32 | SUSPENDED(false), // log string id |
33 | 33 | CREDENTIALS_READ(true), // log device id |
34 | - ATTRIBUTES_READ(true); // log attributes | |
34 | + ATTRIBUTES_READ(true), // log attributes | |
35 | + RELATION_ADD_OR_UPDATE (false), | |
36 | + RELATION_DELETED (false), | |
37 | + RELATIONS_DELETED (false), | |
38 | + ALARM_ACK (false), | |
39 | + ALARM_CLEAR (false); | |
35 | 40 | |
36 | 41 | private final boolean isRead; |
37 | 42 | ... | ... |
... | ... | @@ -40,15 +40,14 @@ public interface AuditLogService { |
40 | 40 | |
41 | 41 | TimePageData<AuditLog> findAuditLogsByTenantId(TenantId tenantId, TimePageLink pageLink); |
42 | 42 | |
43 | - <E extends BaseData<I> & HasName, | |
44 | - I extends UUIDBased & EntityId> ListenableFuture<List<Void>> logEntityAction( | |
45 | - TenantId tenantId, | |
46 | - CustomerId customerId, | |
47 | - UserId userId, | |
48 | - String userName, | |
49 | - I entityId, | |
50 | - E entity, | |
51 | - ActionType actionType, | |
52 | - Exception e, Object... additionalInfo); | |
43 | + <E extends HasName, I extends EntityId> ListenableFuture<List<Void>> logEntityAction( | |
44 | + TenantId tenantId, | |
45 | + CustomerId customerId, | |
46 | + UserId userId, | |
47 | + String userName, | |
48 | + I entityId, | |
49 | + E entity, | |
50 | + ActionType actionType, | |
51 | + Exception e, Object... additionalInfo); | |
53 | 52 | |
54 | 53 | } | ... | ... |
... | ... | @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.id.UserId; |
43 | 43 | import org.thingsboard.server.common.data.kv.AttributeKvEntry; |
44 | 44 | import org.thingsboard.server.common.data.page.TimePageData; |
45 | 45 | import org.thingsboard.server.common.data.page.TimePageLink; |
46 | +import org.thingsboard.server.common.data.relation.EntityRelation; | |
46 | 47 | import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
47 | 48 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
48 | 49 | import org.thingsboard.server.dao.audit.sink.AuditLogSink; |
... | ... | @@ -115,7 +116,7 @@ public class AuditLogServiceImpl implements AuditLogService { |
115 | 116 | } |
116 | 117 | |
117 | 118 | @Override |
118 | - public <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> ListenableFuture<List<Void>> | |
119 | + public <E extends HasName, I extends EntityId> ListenableFuture<List<Void>> | |
119 | 120 | logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, |
120 | 121 | ActionType actionType, Exception e, Object... additionalInfo) { |
121 | 122 | if (canLog(entityId.getEntityType(), actionType)) { |
... | ... | @@ -156,14 +157,16 @@ public class AuditLogServiceImpl implements AuditLogService { |
156 | 157 | } |
157 | 158 | } |
158 | 159 | |
159 | - private <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> JsonNode constructActionData(I entityId, | |
160 | - E entity, | |
160 | + private <E extends HasName, I extends EntityId> JsonNode constructActionData(I entityId, E entity, | |
161 | 161 | ActionType actionType, |
162 | 162 | Object... additionalInfo) { |
163 | 163 | ObjectNode actionData = objectMapper.createObjectNode(); |
164 | 164 | switch(actionType) { |
165 | 165 | case ADDED: |
166 | 166 | case UPDATED: |
167 | + case ALARM_ACK: | |
168 | + case ALARM_CLEAR: | |
169 | + case RELATIONS_DELETED: | |
167 | 170 | if (entity != null) { |
168 | 171 | ObjectNode entityNode = objectMapper.valueToTree(entity); |
169 | 172 | if (entityId.getEntityType() == EntityType.DASHBOARD) { |
... | ... | @@ -240,6 +243,11 @@ public class AuditLogServiceImpl implements AuditLogService { |
240 | 243 | actionData.put("unassignedCustomerId", strCustomerId); |
241 | 244 | actionData.put("unassignedCustomerName", strCustomerName); |
242 | 245 | break; |
246 | + case RELATION_ADD_OR_UPDATE: | |
247 | + case RELATION_DELETED: | |
248 | + EntityRelation relation = extractParameter(EntityRelation.class, 0, additionalInfo); | |
249 | + actionData.set("relation", objectMapper.valueToTree(relation)); | |
250 | + break; | |
243 | 251 | } |
244 | 252 | return actionData; |
245 | 253 | } | ... | ... |
... | ... | @@ -57,7 +57,7 @@ public class DummyAuditLogServiceImpl implements AuditLogService { |
57 | 57 | } |
58 | 58 | |
59 | 59 | @Override |
60 | - public <E extends BaseData<I> & HasName, I extends UUIDBased & EntityId> ListenableFuture<List<Void>> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { | |
60 | + public <E extends HasName, I extends EntityId> ListenableFuture<List<Void>> logEntityAction(TenantId tenantId, CustomerId customerId, UserId userId, String userName, I entityId, E entity, ActionType actionType, Exception e, Object... additionalInfo) { | |
61 | 61 | return null; |
62 | 62 | } |
63 | 63 | ... | ... |
... | ... | @@ -195,6 +195,21 @@ export default angular.module('thingsboard.types', []) |
195 | 195 | }, |
196 | 196 | "ATTRIBUTES_READ": { |
197 | 197 | name: "audit-log.type-attributes-read" |
198 | + }, | |
199 | + "RELATION_ADD_OR_UPDATE": { | |
200 | + name: "audit-log.type-relation-add-or-update" | |
201 | + }, | |
202 | + "RELATION_DELETED": { | |
203 | + name: "audit-log.type-relation-delete" | |
204 | + }, | |
205 | + "RELATIONS_DELETED": { | |
206 | + name: "audit-log.type-relations-delete" | |
207 | + }, | |
208 | + "ALARM_ACK": { | |
209 | + name: "audit-log.type-alarm-ack" | |
210 | + }, | |
211 | + "ALARM_CLEAR": { | |
212 | + name: "audit-log.type-alarm-clear" | |
198 | 213 | } |
199 | 214 | }, |
200 | 215 | auditLogActionStatus: { | ... | ... |
... | ... | @@ -288,6 +288,11 @@ |
288 | 288 | "type-suspended": "Suspended", |
289 | 289 | "type-credentials-read": "Credentials read", |
290 | 290 | "type-attributes-read": "Attributes read", |
291 | + "type-relation-add-or-update": "Relation updated", | |
292 | + "type-relation-delete": "Relation deleted", | |
293 | + "type-relations-delete": "All relation deleted", | |
294 | + "type-alarm-ack": "Acknowledged", | |
295 | + "type-alarm-clear": "Cleared", | |
291 | 296 | "status-success": "Success", |
292 | 297 | "status-failure": "Failure", |
293 | 298 | "audit-log-details": "Audit log details", | ... | ... |