MQTT
This commit is contained in:
177
STOMP_README.md
177
STOMP_README.md
@@ -1,177 +0,0 @@
|
|||||||
# VOTIANLT Realtime & Photo Upload API
|
|
||||||
|
|
||||||
This document describes how mobile/Flutter apps can interact with the backend via STOMP (WebSocket) and how to upload photos via HTTP POST (new flow).
|
|
||||||
|
|
||||||
## 1) STOMP Overview
|
|
||||||
|
|
||||||
- Connect to one of the WebSocket endpoints:
|
|
||||||
- `/ws` (SockJS fallback supported)
|
|
||||||
- `/websocket` (native WebSocket)
|
|
||||||
- `/stomp` (native WebSocket, alternate path)
|
|
||||||
- Application destination prefix: `/app`
|
|
||||||
- Broker destinations:
|
|
||||||
- Broadcast: `/topic/...`
|
|
||||||
- User specific: `/user/queue/...`
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- Send a generic message: send to `/app/message`, receive on `/topic/messages`
|
|
||||||
- Job updates: send to `/app/job/status`, receive on `/topic/job-updates`
|
|
||||||
- Device locations: send to `/app/device/location`, receive on `/topic/device-locations`
|
|
||||||
- Task updates (broadcast): `/topic/task-updates`
|
|
||||||
- Task specific topic: `/topic/tasks/{taskId}`
|
|
||||||
|
|
||||||
## 2) Photo Task – New HTTP Upload Flow
|
|
||||||
|
|
||||||
In the future, photos for a PHOTO task must NOT be embedded in the STOMP message anymore. Instead, upload the photos via HTTP POST and only send the task-completion event via STOMP without large payloads.
|
|
||||||
|
|
||||||
### Endpoint
|
|
||||||
|
|
||||||
- URL: `POST /api/tasks/{taskId}/photos`
|
|
||||||
- Purpose: Upload one or many photos for a task of type `PHOTO`.
|
|
||||||
- Path params:
|
|
||||||
- `taskId` (required): The MongoDB ObjectId of the task.
|
|
||||||
- Auth: (same as your app uses today; if you have a session/cookie or token, include it accordingly)
|
|
||||||
- CORS: Enabled for `*` by default on this controller.
|
|
||||||
|
|
||||||
### Content Types (choose one)
|
|
||||||
|
|
||||||
1) Multipart form data (recommended for binary images)
|
|
||||||
|
|
||||||
- `Content-Type: multipart/form-data`
|
|
||||||
- Fields:
|
|
||||||
- `files`: one or multiple image files (repeat the field for multiple images)
|
|
||||||
- `completedBy` (optional): username/id of the completing user
|
|
||||||
- `note` (optional): any note (currently stored on the task when you mark it as completed via STOMP)
|
|
||||||
|
|
||||||
Example (curl):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:8080/api/tasks/66f5c2f1a3b6e27a1a234567/photos" \
|
|
||||||
-H "Content-Type: multipart/form-data" \
|
|
||||||
-F "files=@/path/to/photo1.jpg" \
|
|
||||||
-F "files=@/path/to/photo2.jpg" \
|
|
||||||
-F "completedBy=driver01" \
|
|
||||||
-F "note=Anlieferung dokumentiert"
|
|
||||||
```
|
|
||||||
|
|
||||||
2) JSON with base64 strings (kept for compatibility)
|
|
||||||
|
|
||||||
- `Content-Type: application/json`
|
|
||||||
- Body:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"completedBy": "driver01",
|
|
||||||
"note": "Anlieferung dokumentiert",
|
|
||||||
"photos": [
|
|
||||||
"<base64-of-image-1>",
|
|
||||||
"<base64-of-image-2>"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Example (curl):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:8080/api/tasks/66f5c2f1a3b6e27a1a234567/photos" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"completedBy":"driver01",
|
|
||||||
"note":"Anlieferung dokumentiert",
|
|
||||||
"photos":["iVBORw0KGgo...","iVBORw0KGgo..."]
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Simple JSON endpoint (single photo per call)
|
|
||||||
|
|
||||||
- URL: `POST /api/photos`
|
|
||||||
- Content-Type: `application/json`
|
|
||||||
- Body:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"taskId": "66f5c2f1a3b6e27a1a234567",
|
|
||||||
"photo": "<base64-of-image>",
|
|
||||||
"completedBy": "driver01",
|
|
||||||
"note": "optional"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Multiple photos: call this endpoint multiple times (one image per request).
|
|
||||||
|
|
||||||
Example (curl):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X POST "http://localhost:8080/api/photos" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d '{
|
|
||||||
"taskId":"66f5c2f1a3b6e27a1a234567",
|
|
||||||
"photo":"iVBORw0KGgo...",
|
|
||||||
"completedBy":"driver01",
|
|
||||||
"note":"Anlieferung dokumentiert"
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Response
|
|
||||||
|
|
||||||
Both content types return the same JSON structure on success:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"timestamp": "2025-09-13T21:27:00",
|
|
||||||
"type": "photoUploadAck",
|
|
||||||
"success": true,
|
|
||||||
"photoId": "66f5c400b1a1b05b1c123abc",
|
|
||||||
"photosCount": 2,
|
|
||||||
"taskId": "66f5c2f1a3b6e27a1a234567",
|
|
||||||
"jobId": "66f5c2f1a3b6e27a1a200000"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Error responses use HTTP status codes with:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{ "timestamp": "...", "type": "photoUploadAck", "success": false, "message": "..." }
|
|
||||||
```
|
|
||||||
|
|
||||||
### Server-side side-effect (notification)
|
|
||||||
|
|
||||||
After a successful upload, a small event is broadcast to the specific task topic:
|
|
||||||
|
|
||||||
- Destination: `/topic/tasks/{taskId}`
|
|
||||||
- Payload:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{ "event": "photoUploaded", "taskId": "...", "jobId": "...", "photosCount": 2, "timestamp": "..." }
|
|
||||||
```
|
|
||||||
|
|
||||||
Use this to update UI (e.g., show that photos have arrived) without transferring large images via STOMP.
|
|
||||||
|
|
||||||
### Limits
|
|
||||||
|
|
||||||
- Multipart limits (configurable in `application.properties`):
|
|
||||||
- `spring.servlet.multipart.max-file-size=32MB`
|
|
||||||
- `spring.servlet.multipart.max-request-size=64MB`
|
|
||||||
- Tomcat limits adjusted accordingly.
|
|
||||||
|
|
||||||
If you need higher limits, we can raise these values.
|
|
||||||
|
|
||||||
## 3) Marking Task as Completed (STOMP)
|
|
||||||
|
|
||||||
Continue to mark a task as completed via STOMP without embedding images:
|
|
||||||
|
|
||||||
- Send to: `/app/task/photo/completed`
|
|
||||||
- Payload (no photos inside):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{ "taskId": "66f5c2f1a3b6e27a1a234567", "completedBy": "driver01", "note": "Anlieferung dokumentiert" }
|
|
||||||
```
|
|
||||||
|
|
||||||
- Broadcasts an update to `/topic/task-updates` and `/topic/tasks/{taskId}`.
|
|
||||||
|
|
||||||
## 4) Retrieval of Photos (optional)
|
|
||||||
|
|
||||||
Currently, the backend stores uploaded photos as base64 in the `photos` collection referencing the `taskId` and `jobId`. If you need a download/list endpoint, let us know—we can expose `/api/tasks/{taskId}/photos` (GET) to return metadata and/or images.
|
|
||||||
|
|
||||||
---
|
|
||||||
If anything is unclear or you need different formats (e.g., presigned URLs, chunked uploads), please reach out.
|
|
||||||
@@ -27,8 +27,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* STOMP message controller for handling real-time communication with apps.
|
* MQTT message controller for handling real-time communication with apps.
|
||||||
* Provides endpoints for sending and receiving messages via WebSocket/STOMP.
|
* Provides endpoints for sending and receiving messages via WebSocket/MQTT.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -59,14 +59,14 @@ public class MessageController {
|
|||||||
* Handles messages sent to /app/message and broadcasts them to all subscribers of /topic/messages
|
* Handles messages sent to /app/message and broadcasts them to all subscribers of /topic/messages
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleMessage(Map<String, Object> message) {
|
public Map<String, Object> handleMessage(Map<String, Object> message) {
|
||||||
log.error("=== ANY MESSAGE RECEIVED === STOMP Endpoint '/app/message' called");
|
log.error("=== ANY MESSAGE RECEIVED === MQTT Endpoint '/app/message' called");
|
||||||
log.info("STOMP Endpoint '/app/message' called with data: {}", message);
|
log.info("MQTT Endpoint '/app/message' called with data: {}", message);
|
||||||
|
|
||||||
// Add timestamp to the message
|
// Add timestamp to the message
|
||||||
message.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
message.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
message.put("processed", true);
|
message.put("processed", true);
|
||||||
|
|
||||||
log.info("STOMP Response for '/app/message' sent to '/topic/messages': {}", message);
|
log.info("MQTT Response for '/app/message' sent to '/topic/messages': {}", message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,12 +74,12 @@ public class MessageController {
|
|||||||
* Handles job status updates from apps
|
* Handles job status updates from apps
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleJobStatusUpdate(Map<String, Object> jobUpdate) {
|
public Map<String, Object> handleJobStatusUpdate(Map<String, Object> jobUpdate) {
|
||||||
log.info("STOMP Endpoint '/app/job/status' called with data: {}", jobUpdate);
|
log.info("MQTT Endpoint '/app/job/status' called with data: {}", jobUpdate);
|
||||||
|
|
||||||
jobUpdate.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
jobUpdate.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
jobUpdate.put("source", "app");
|
jobUpdate.put("source", "app");
|
||||||
|
|
||||||
log.info("STOMP Response for '/app/job/status' sent to '/topic/job-updates': {}", jobUpdate);
|
log.info("MQTT Response for '/app/job/status' sent to '/topic/job-updates': {}", jobUpdate);
|
||||||
return jobUpdate;
|
return jobUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +87,12 @@ public class MessageController {
|
|||||||
* Handles device location updates from mobile apps
|
* Handles device location updates from mobile apps
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleDeviceLocation(Map<String, Object> locationUpdate) {
|
public Map<String, Object> handleDeviceLocation(Map<String, Object> locationUpdate) {
|
||||||
log.info("STOMP Endpoint '/app/device/location' called with data: {}", locationUpdate);
|
log.info("MQTT Endpoint '/app/device/location' called with data: {}", locationUpdate);
|
||||||
|
|
||||||
locationUpdate.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
locationUpdate.put("timestamp", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
|
||||||
locationUpdate.put("processed", true);
|
locationUpdate.put("processed", true);
|
||||||
|
|
||||||
log.info("STOMP Response for '/app/device/location' sent to '/topic/device-locations': {}", locationUpdate);
|
log.info("MQTT Response for '/app/device/location' sent to '/topic/device-locations': {}", locationUpdate);
|
||||||
return locationUpdate;
|
return locationUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,18 +127,18 @@ public class MessageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authentication endpoint for mobile app users via STOMP.
|
* Authentication endpoint for mobile app users via MQTT.
|
||||||
* Client sends to /app/auth/login with payload { email, password }.
|
* Client sends to /app/auth/login with payload { email, password }.
|
||||||
* The response is sent back to the requesting user on /user/queue/auth
|
* The response is sent back to the requesting user on /user/queue/auth
|
||||||
*/
|
*/
|
||||||
public AppLoginResponse handleAppLogin(AppLoginRequest request) {
|
public AppLoginResponse handleAppLogin(AppLoginRequest request) {
|
||||||
log.info("STOMP Endpoint '/app/auth/login' called with email: {}",
|
log.info("MQTT Endpoint '/app/auth/login' called with email: {}",
|
||||||
request != null ? request.getEmail() : "null");
|
request != null ? request.getEmail() : "null");
|
||||||
|
|
||||||
if (request == null || request.getEmail() == null || request.getPassword() == null
|
if (request == null || request.getEmail() == null || request.getPassword() == null
|
||||||
|| request.getEmail().isBlank() || request.getPassword().isBlank()) {
|
|| request.getEmail().isBlank() || request.getPassword().isBlank()) {
|
||||||
AppLoginResponse response = new AppLoginResponse(false, "E-Mail und Passwort sind erforderlich", null, null, null);
|
AppLoginResponse response = new AppLoginResponse(false, "E-Mail und Passwort sind erforderlich", null, null, null);
|
||||||
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
log.info("MQTT Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
||||||
false, "E-Mail und Passwort sind erforderlich");
|
false, "E-Mail und Passwort sind erforderlich");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ public class MessageController {
|
|||||||
AppUser user = appUserRepository.findByEmail(request.getEmail());
|
AppUser user = appUserRepository.findByEmail(request.getEmail());
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
AppLoginResponse response = new AppLoginResponse(false, "Benutzer nicht gefunden", null, null, null);
|
AppLoginResponse response = new AppLoginResponse(false, "Benutzer nicht gefunden", null, null, null);
|
||||||
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
log.info("MQTT Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
||||||
false, "Benutzer nicht gefunden");
|
false, "Benutzer nicht gefunden");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -154,13 +154,13 @@ public class MessageController {
|
|||||||
boolean ok = appUserService.verifyPassword(request.getPassword(), user.getPassword());
|
boolean ok = appUserService.verifyPassword(request.getPassword(), user.getPassword());
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
AppLoginResponse response = new AppLoginResponse(false, "Ungültige Anmeldedaten", null, null, null);
|
AppLoginResponse response = new AppLoginResponse(false, "Ungültige Anmeldedaten", null, null, null);
|
||||||
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
log.info("MQTT Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}'",
|
||||||
false, "Ungültige Anmeldedaten");
|
false, "Ungültige Anmeldedaten");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppLoginResponse response = new AppLoginResponse(true, "Anmeldung erfolgreich", null, null, user.getIdAsString());
|
AppLoginResponse response = new AppLoginResponse(true, "Anmeldung erfolgreich", null, null, user.getIdAsString());
|
||||||
log.info("STOMP Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}', appUserId='{}'",
|
log.info("MQTT Response for '/app/auth/login' sent to '/user/queue/auth': success={}, message='{}', appUserId='{}'",
|
||||||
true, "Anmeldung erfolgreich", response.getAppUserId());
|
true, "Anmeldung erfolgreich", response.getAppUserId());
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
@@ -171,17 +171,17 @@ public class MessageController {
|
|||||||
* The response is sent back to the requesting user on /user/queue/jobs
|
* The response is sent back to the requesting user on /user/queue/jobs
|
||||||
*/
|
*/
|
||||||
public List<JobWithRelatedDataDTO> handleGetAssignedJobs(Map<String, Object> request) {
|
public List<JobWithRelatedDataDTO> handleGetAssignedJobs(Map<String, Object> request) {
|
||||||
log.info("STOMP Endpoint '/app/jobs/assigned' called with data: {}", request);
|
log.info("MQTT Endpoint '/app/jobs/assigned' called with data: {}", request);
|
||||||
log.debug("Starting to process jobs request for STOMP endpoint");
|
log.debug("Starting to process jobs request for MQTT endpoint");
|
||||||
|
|
||||||
if (request == null || !request.containsKey("appUserId")) {
|
if (request == null || !request.containsKey("appUserId")) {
|
||||||
log.info("STOMP Response for '/app/jobs/assigned' sent to '/user/queue/jobs': empty list (no appUserId provided)");
|
log.info("MQTT Response for '/app/jobs/assigned' sent to '/user/queue/jobs': empty list (no appUserId provided)");
|
||||||
return List.of(); // Return empty list if no appUserId provided
|
return List.of(); // Return empty list if no appUserId provided
|
||||||
}
|
}
|
||||||
|
|
||||||
String appUserId = request.get("appUserId").toString();
|
String appUserId = request.get("appUserId").toString();
|
||||||
if (appUserId == null || appUserId.isBlank()) {
|
if (appUserId == null || appUserId.isBlank()) {
|
||||||
log.info("STOMP Response for '/app/jobs/assigned' sent to '/user/queue/jobs': empty list (appUserId is blank)");
|
log.info("MQTT Response for '/app/jobs/assigned' sent to '/user/queue/jobs': empty list (appUserId is blank)");
|
||||||
return List.of(); // Return empty list if appUserId is blank
|
return List.of(); // Return empty list if appUserId is blank
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ public class MessageController {
|
|||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
log.info("STOMP Response for '/app/jobs/assigned' sent to '/user/queue/jobs': {} jobs with related data found for appUserId='{}'",
|
log.info("MQTT Response for '/app/jobs/assigned' sent to '/user/queue/jobs': {} jobs with related data found for appUserId='{}'",
|
||||||
jobsWithRelatedData.size(), appUserId);
|
jobsWithRelatedData.size(), appUserId);
|
||||||
|
|
||||||
// Log complete JSON for debugging
|
// Log complete JSON for debugging
|
||||||
@@ -214,7 +214,7 @@ public class MessageController {
|
|||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
objectMapper.registerModule(new JavaTimeModule());
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
String jsonOutput = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jobsWithRelatedData);
|
String jsonOutput = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jobsWithRelatedData);
|
||||||
log.info("=== COMPLETE JSON RESPONSE FOR STOMP CLIENT ===");
|
log.info("=== COMPLETE JSON RESPONSE FOR MQTT CLIENT ===");
|
||||||
log.info("AppUserId: {}", appUserId);
|
log.info("AppUserId: {}", appUserId);
|
||||||
log.info("Number of jobs: {}", jobsWithRelatedData.size());
|
log.info("Number of jobs: {}", jobsWithRelatedData.size());
|
||||||
log.info("JSON Data:\n{}", jsonOutput);
|
log.info("JSON Data:\n{}", jsonOutput);
|
||||||
@@ -233,7 +233,7 @@ public class MessageController {
|
|||||||
* This endpoint accepts any task type (fallback for GENERIC or unknown types).
|
* This endpoint accepts any task type (fallback for GENERIC or unknown types).
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleTaskCompleted(Map<String, Object> payload) {
|
public Map<String, Object> handleTaskCompleted(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/completed' called with data: {}", payload);
|
log.info("MQTT Endpoint '/app/task/completed' called with data: {}", payload);
|
||||||
return processTaskCompletion(payload, null); // null means accept any task type
|
return processTaskCompletion(payload, null); // null means accept any task type
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ public class MessageController {
|
|||||||
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleTaskConfirmation(Map<String, Object> payload) {
|
public Map<String, Object> handleTaskConfirmation(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/confirm' called with data: {}", payload);
|
log.info("MQTT Endpoint '/app/task/confirm' called with data: {}", payload);
|
||||||
return processTaskCompletion(payload, "CONFIRMATION");
|
return processTaskCompletion(payload, "CONFIRMATION");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ public class MessageController {
|
|||||||
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handlePhotoTaskCompleted(Map<String, Object> payload) {
|
public Map<String, Object> handlePhotoTaskCompleted(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/photo/completed' called");
|
log.info("MQTT Endpoint '/app/task/photo/completed' called");
|
||||||
return processPhotoTaskCompletion(payload);
|
return processPhotoTaskCompletion(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ public class MessageController {
|
|||||||
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleSignatureTaskCompleted(Map<String, Object> payload) {
|
public Map<String, Object> handleSignatureTaskCompleted(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/signature/completed' called with data: {}", payload);
|
log.info("MQTT Endpoint '/app/task/signature/completed' called with data: {}", payload);
|
||||||
return processTaskCompletion(payload, "SIGNATURE");
|
return processTaskCompletion(payload, "SIGNATURE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +274,7 @@ public class MessageController {
|
|||||||
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleBarcodeTaskCompleted(Map<String, Object> payload) {
|
public Map<String, Object> handleBarcodeTaskCompleted(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/barcode/completed' called with data: {}", payload);
|
log.info("MQTT Endpoint '/app/task/barcode/completed' called with data: {}", payload);
|
||||||
return processTaskCompletion(payload, "BARCODE");
|
return processTaskCompletion(payload, "BARCODE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ public class MessageController {
|
|||||||
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
* Broadcasts to /topic/task-updates and /topic/tasks/{taskId}.
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> handleTodolistTaskCompleted(Map<String, Object> payload) {
|
public Map<String, Object> handleTodolistTaskCompleted(Map<String, Object> payload) {
|
||||||
log.info("STOMP Endpoint '/app/task/todolist/completed' called with data: {}", payload);
|
log.info("MQTT Endpoint '/app/task/todolist/completed' called with data: {}", payload);
|
||||||
return processTaskCompletion(payload, "TODOLIST");
|
return processTaskCompletion(payload, "TODOLIST");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class SecurityConfig extends VaadinWebSecurity {
|
|||||||
).permitAll()
|
).permitAll()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Standard-CSRF-Konfiguration (keine speziellen WebSocket/STOMP-Ausnahmen mehr notwendig)
|
// Standard-CSRF-Konfiguration
|
||||||
http.csrf(csrf -> csrf
|
http.csrf(csrf -> csrf
|
||||||
.ignoringRequestMatchers(
|
.ignoringRequestMatchers(
|
||||||
new AntPathRequestMatcher("/h2-console/**")
|
new AntPathRequestMatcher("/h2-console/**")
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ server.tomcat.max-swallow-size=64MB
|
|||||||
# Multipart upload limits for photo HTTP uploads
|
# Multipart upload limits for photo HTTP uploads
|
||||||
spring.servlet.multipart.max-file-size=32MB
|
spring.servlet.multipart.max-file-size=32MB
|
||||||
spring.servlet.multipart.max-request-size=64MB
|
spring.servlet.multipart.max-request-size=64MB
|
||||||
# Additional WebSocket and messaging limits for large payloads
|
|
||||||
# STOMP broker relay limits
|
|
||||||
# Jackson message converter limits
|
# Jackson message converter limits
|
||||||
spring.jackson.default-property-inclusion=non_null
|
spring.jackson.default-property-inclusion=non_null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user