Skip to content

Commit e060984

Browse files
Merge branch 'main' into dependabot/maven/com.sap.cloud.sdk-sdk-bom-5.23.0
2 parents c418619 + 72a7f44 commit e060984

File tree

10 files changed

+177
-88
lines changed

10 files changed

+177
-88
lines changed

.github/workflows/codeql.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ jobs:
5555
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
5656
steps:
5757
- name: Checkout repository
58-
uses: actions/checkout@v4
58+
uses: actions/checkout@v5
5959

6060
# Initializes the CodeQL tools for scanning.
6161
- name: Initialize CodeQL
62-
uses: github/codeql-action/init@v3
62+
uses: github/codeql-action/init@v4
6363
with:
6464
languages: ${{ matrix.language }}
6565
build-mode: ${{ matrix.build-mode }}
@@ -87,6 +87,6 @@ jobs:
8787
exit 1
8888
8989
- name: Perform CodeQL Analysis
90-
uses: github/codeql-action/analyze@v3
90+
uses: github/codeql-action/analyze@v4
9191
with:
9292
category: "/language:${{matrix.language}}"

.github/workflows/main-build-and-deploy-oss.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
# timeout-minutes: 15
1616
# steps:
1717
# - name: Checkout
18-
# uses: actions/checkout@v4
18+
# uses: actions/checkout@v5
1919
# - name: Scan With Black Duck
2020
# uses: ./.github/actions/scan-with-blackduck
2121
# with:
@@ -28,7 +28,7 @@ jobs:
2828
runs-on: ubuntu-latest
2929
steps:
3030
- name: Checkout
31-
uses: actions/checkout@v4
31+
uses: actions/checkout@v5
3232
with:
3333
token: ${{ secrets.GH_TOKEN }}
3434
- name: Update version

.github/workflows/main-build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
java-version: [ 17, 21 ]
1818
steps:
1919
- name: Checkout
20-
uses: actions/checkout@v4
20+
uses: actions/checkout@v5
2121

2222
- name: Build
2323
uses: ./.github/actions/build
@@ -40,7 +40,7 @@ jobs:
4040
# timeout-minutes: 15
4141
# steps:
4242
# - name: Checkout
43-
# uses: actions/checkout@v4
43+
# uses: actions/checkout@v5
4444
# - name: Scan
4545
# uses: ./.github/actions/scan-with-blackduck
4646
# with:
@@ -54,10 +54,10 @@ jobs:
5454
needs: [build] # [build, scan]
5555
steps:
5656
- name: Checkout
57-
uses: actions/checkout@v4
57+
uses: actions/checkout@v5
5858

5959
- name: Set up Java ${{ env.JAVA_VERSION }}
60-
uses: actions/setup-java@v4
60+
uses: actions/setup-java@v5
6161
with:
6262
java-version: ${{ env.JAVA_VERSION }}
6363
distribution: sapmachine

.github/workflows/pull-request-build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818

1919
steps:
2020
- name: Checkout
21-
uses: actions/checkout@v4
21+
uses: actions/checkout@v5
2222

2323
- name: Build
2424
uses: ./.github/actions/build

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## Version 0.0.2 - 2025-10-30
9+
10+
### Added
11+
12+
- Support for sending generic audit log events
13+
814
## Version 0.0.1 - 2025-07-04
915

1016
### Added

cds-feature-auditlog-ng/src/main/java/com/sap/cds/feature/auditlog/ng/AuditLogNGCommunicator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public AuditLogNGCommunicator(ServiceBinding binding) {
6868
}
6969
}
7070

71-
public String sendBulkRequest(Object auditLogEvents) throws JsonProcessingException {
71+
String sendBulkRequest(Object auditLogEvents) throws JsonProcessingException {
7272
logger.debug("Sending bulk request to audit log service");
7373
String bulkRequestJson = serializeBulkRequest(auditLogEvents);
7474
HttpPost request = new HttpPost(serviceUrl + AUDITLOG_EVENTS_ENDPOINT);

cds-feature-auditlog-ng/src/main/java/com/sap/cds/feature/auditlog/ng/AuditLogNGHandler.java

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,22 @@
33
*/
44
package com.sap.cds.feature.auditlog.ng;
55

6+
import static java.util.Objects.*;
7+
import static org.slf4j.LoggerFactory.*;
8+
69
import java.time.Instant;
710
import java.util.Collection;
8-
import static java.util.Objects.requireNonNull;
11+
import java.util.Map;
912
import java.util.UUID;
1013
import java.util.stream.Collectors;
1114

1215
import org.slf4j.Logger;
13-
import static org.slf4j.LoggerFactory.getLogger;
1416

15-
import com.fasterxml.jackson.core.JsonParseException;
1617
import com.fasterxml.jackson.core.JsonProcessingException;
1718
import com.fasterxml.jackson.databind.ObjectMapper;
1819
import com.fasterxml.jackson.databind.node.ArrayNode;
1920
import com.fasterxml.jackson.databind.node.ObjectNode;
21+
import com.sap.cds.services.EventContext;
2022
import com.sap.cds.services.auditlog.Access;
2123
import com.sap.cds.services.auditlog.Attachment;
2224
import com.sap.cds.services.auditlog.Attribute;
@@ -62,22 +64,66 @@ public class AuditLogNGHandler implements EventHandler {
6264
}
6365

6466
@On
65-
public void handleSecurityEvent(SecurityLogContext context) {
67+
public void handleGeneralEvent(EventContext context) {
6668
try {
67-
ArrayNode alsEvents = createSecurityEvent(context);
68-
communicator.sendBulkRequest(alsEvents);
69-
} catch (JsonParseException e) {
70-
LOGGER.error("Audit Log write exception occurred for security event", e);
69+
if (context instanceof SecurityLogContext || context.getEvent().equals("securityLog")) {
70+
LOGGER.debug("Handling security log event");
71+
handleSecurityEvent(context.as(SecurityLogContext.class));
72+
return;
73+
} else if (context instanceof DataAccessLogContext || context.getEvent().equals("dataAccessLog")) {
74+
LOGGER.debug("Handling data access log event");
75+
handleDataAccessEvent(context.as(DataAccessLogContext.class));
76+
return;
77+
} else if (context instanceof ConfigChangeLogContext || context.getEvent().equals("configChangeLog")) {
78+
LOGGER.debug("Handling configuration change log event");
79+
handleConfigChangeEvent(context.as(ConfigChangeLogContext.class));
80+
return;
81+
} else if (context instanceof DataModificationLogContext || context.getEvent().equals("dataModificationLog")) {
82+
LOGGER.debug("Handling data modification log event");
83+
handleDataModificationEvent(context.as(DataModificationLogContext.class));
84+
return;
85+
} else {
86+
ArrayNode alsEvents = createGeneralEvent(context);
87+
communicator.sendBulkRequest(alsEvents);
88+
}
89+
} catch (JsonProcessingException e) {
90+
LOGGER.error("Audit Log write exception occurred", e);
7191
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
7292
} catch (ErrorStatusException e) {
73-
LOGGER.error("Audit Log service not available for security event", e);
93+
LOGGER.error("Audit Log service not available", e);
7494
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_NOT_AVAILABLE, e);
75-
} catch (Exception e) {
76-
LOGGER.error("Unexpected exception while handling security event", e);
95+
} catch (Exception e) {
96+
LOGGER.error("Unexpected exception", e);
7797
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
7898
}
7999
}
80100

101+
private ArrayNode createGeneralEvent(EventContext context) throws JsonProcessingException {
102+
UserInfo userInfo = requireNonNull(context.getUserInfo(), "UserInfo in EventContext must not be null");
103+
String eventType = requireNonNull((String) context.getEvent(), "EventType in EventContext must not be null");
104+
Map<String, Object> data = (Map<String, Object>) context.get("data");
105+
String eventJson = (String) data.get("event");
106+
107+
ObjectNode eventEnvelope = buildEventEnvelope(OBJECT_MAPPER, eventType, userInfo);
108+
ObjectNode metadata = buildEventMetadata();
109+
ObjectNode parsedEventNode = (ObjectNode) OBJECT_MAPPER.readTree(eventJson);
110+
ObjectNode wrappedDataNode = OBJECT_MAPPER.createObjectNode();
111+
wrappedDataNode.set(eventType, parsedEventNode);
112+
ObjectNode alsData = buildAuditLogEventData(metadata, wrappedDataNode);
113+
eventEnvelope.set("data", alsData);
114+
115+
ArrayNode result = OBJECT_MAPPER.createArrayNode();
116+
result.add(eventEnvelope);
117+
118+
LOGGER.debug("Created general event for Audit Log NG: {}", result.toString());
119+
return result;
120+
}
121+
122+
public void handleSecurityEvent(SecurityLogContext context) throws JsonProcessingException {
123+
ArrayNode alsEvents = createSecurityEvent(context);
124+
communicator.sendBulkRequest(alsEvents);
125+
}
126+
81127
/**
82128
* Creates an ArrayNode representing security events for the Audit Log service.
83129
*
@@ -141,21 +187,9 @@ private ObjectNode createLegacySecurityOrigEvent(UserInfo userInfo, SecurityLog
141187
return envelop;
142188
}
143189

144-
@On
145-
public void handleDataAccessEvent(DataAccessLogContext context) {
146-
try {
147-
ArrayNode alsEvents = createAlsDataAccessEvents(context);
148-
communicator.sendBulkRequest(alsEvents);
149-
} catch (JsonParseException e) {
150-
LOGGER.error("Audit Log write exception occurred for data access event", e);
151-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
152-
} catch (ErrorStatusException e) {
153-
LOGGER.error("Audit Log service not available for data access event", e);
154-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_NOT_AVAILABLE, e);
155-
} catch (Exception e) {
156-
LOGGER.error("Unexpected exception while handling data access event", e);
157-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
158-
}
190+
public void handleDataAccessEvent(DataAccessLogContext context) throws JsonProcessingException {
191+
ArrayNode alsEvents = createAlsDataAccessEvents(context);
192+
communicator.sendBulkRequest(alsEvents);
159193
}
160194

161195
/**
@@ -221,21 +255,9 @@ private void addAttributeAccessEvents(UserInfo userInfo, ArrayNode eventArray, A
221255
}
222256
}
223257

224-
@On
225-
public void handleConfigChangeEvent(ConfigChangeLogContext context) {
226-
try {
227-
ArrayNode alsEvents = createAlsConfigChangeEvents(context);
228-
communicator.sendBulkRequest(alsEvents);
229-
} catch (JsonParseException e) {
230-
LOGGER.error("Audit Log write exception occurred for configuration change event", e);
231-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
232-
} catch (ErrorStatusException e) {
233-
LOGGER.error("Audit Log service not available for configuration change event", e);
234-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_NOT_AVAILABLE, e);
235-
} catch (Exception e) {
236-
LOGGER.error("Unexpected exception while handling configuration change event", e);
237-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
238-
}
258+
public void handleConfigChangeEvent(ConfigChangeLogContext context) throws JsonProcessingException {
259+
ArrayNode alsEvents = createAlsConfigChangeEvents(context);
260+
communicator.sendBulkRequest(alsEvents);
239261
}
240262

241263
/**
@@ -280,21 +302,9 @@ private ObjectNode buildConfigChangeEvent(UserInfo userInfo, ConfigChange config
280302
return buildAlsEvent("configurationChange", userInfo, metadata, "configurationChange", changeNode);
281303
}
282304

283-
@On
284-
public void handleDataModificationEvent(DataModificationLogContext context) {
285-
try {
286-
ArrayNode alsEvents = createAlsDataModificationEvents(context);
287-
communicator.sendBulkRequest(alsEvents);
288-
} catch (JsonParseException e) {
289-
LOGGER.error("Audit Log write exception occurred for data modification event", e);
290-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
291-
} catch (ErrorStatusException e) {
292-
LOGGER.error("Audit Log service not available for data modification event", e);
293-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_NOT_AVAILABLE, e);
294-
} catch (Exception e) {
295-
LOGGER.error("Unexpected exception while handling data modification event", e);
296-
throw new ErrorStatusException(CdsErrorStatuses.AUDITLOG_SERVICE_INVALID_MESSAGE, e);
297-
}
305+
public void handleDataModificationEvent(DataModificationLogContext context) throws JsonProcessingException {
306+
ArrayNode alsEvents = createAlsDataModificationEvents(context);
307+
communicator.sendBulkRequest(alsEvents);
298308
}
299309

300310
/**
@@ -473,9 +483,8 @@ private ObjectNode buildDataAccessNode(Access access, String attribute, String a
473483
*/
474484
private void addValueDetails(ObjectNode node, ChangedAttribute attribute, String fieldName) {
475485
String attributeName = requireNonNull(attribute.getName(), "ChangedAttribute.getName() is null");
476-
String newValue = requireNonNull(attribute.getNewValue(), "ChangedAttribute.getNewValue() is null");
477486
node.put(fieldName, attributeName);
478-
node.put("newValue", newValue);
487+
node.put("newValue", attribute.getNewValue() != null ? attribute.getNewValue() : "null");
479488
node.put("oldValue", attribute.getOldValue() != null ? attribute.getOldValue() : "null");
480489
}
481490

0 commit comments

Comments
 (0)