Implement scheduler function to send FileReadyNotifications to all subscribers every... 80/15180/3
authorsunil.n <sunil.n@samsung.com>
Mon, 3 Nov 2025 06:44:19 +0000 (12:14 +0530)
committersunil.n <sunil.n@samsung.com>
Tue, 4 Nov 2025 06:50:24 +0000 (12:20 +0530)
Change-Id: I1e363a020bea383a2ad269e8a042ea8c478eb8a3
Signed-off-by: sunil.n <sunil.n@samsung.com>
sample-rapp-generator/rapp-ran-nssmf-simulator/README.md
sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/controller/FileDataReportingMnSController.java
sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/DateTimeDTO.java [new file with mode: 0644]
sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/FileInfoDTO.java [new file with mode: 0644]
sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotificationHeaderDTO.java [new file with mode: 0644]
sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotifyFileReadyDTO.java [new file with mode: 0644]

index e9d7f2d..2ac5cbd 100644 (file)
@@ -1,6 +1,6 @@
 5G RAN NSSMF Simulator Rapp
 
-5G RAN NSSMF Simulator Rapp implements 5G RAN NSSMF Interfaces for subscriptions, NSSI creation, modifiction, get and delete apis according to 3GPP 28.532
+5G RAN NSSMF Simulator Rapp implements 5G RAN NSSMF Interfaces for subscriptions, NSSI creation, modification, get and delete APIs according to 3GPP 28.532
 
 ## API Documentation
 
@@ -40,6 +40,7 @@
 - Stores subscription details in memory
 - Returns the subscription location in the `Location` header
 - Logs all subscription operations for debugging
+- Sends automated file ready notifications every 5 minutes to all active subscribers
 
 #### Example Usage
 
@@ -64,14 +65,182 @@ Content-Type: application/json
 }
 ```
 
+### File Ready Notification API
+
+#### Automated Notifications
+The simulator automatically sends file ready notifications to all subscribed endpoints every 5 minutes.
+
+**Notification Endpoint**: The callback URL provided during subscription
+**Method**: `POST`
+**Content-Type**: `application/json`
+
+#### Notification Body Structure
+```json
+{
+  "notificationHeader": {
+    "notificationId": "notif-1234567890",
+    "notificationType": "notifyFileReady",
+    "eventTime": {
+      "dateTime": "2025-01-03T12:09:48.123"
+    }
+  },
+  "fileInfoList": [
+    {
+      "fileLocation": "http://example.com/files/sample-performance-data-1234567890.csv",
+      "fileSize": 1024,
+      "fileReadyTime": {
+        "dateTime": "2025-01-03T12:09:48.123"
+      },
+      "fileExpirationTime": {
+        "dateTime": "2025-01-04T12:09:48.123"
+      },
+      "fileCompression": "gzip",
+      "fileFormat": "CSV",
+      "fileDataType": "Performance",
+      "jobId": "job-1234567890"
+    }
+  ],
+  "additionalText": "Sample file ready notification from NSSMF simulator"
+}
+```
+
+#### Notification Fields Description
+
+**NotificationHeader:**
+- `notificationId`: Unique identifier for the notification
+- `notificationType`: Type of notification (always "notifyFileReady")
+- `eventTime`: Timestamp when the notification was generated
+
+**FileInfo:**
+- `fileLocation`: URL where the file can be accessed
+- `fileSize`: Size of the file in bytes
+- `fileReadyTime`: Timestamp when the file became available
+- `fileExpirationTime`: Timestamp when the file will expire
+- `fileCompression`: Compression format used (e.g., "gzip")
+- `fileFormat`: File format (e.g., "CSV", "JSON")
+- `fileDataType`: Type of data in the file (e.g., "Performance")
+- `jobId`: Unique identifier for the job that generated the file
+
 #### Implementation Details
 - **Subscription Storage**: In-memory HashMap (subscriptionMap)
 - **ID Generation**: Sequential integer starting from 1
 - **3GPP Version**: v17.0.0
 - **Server Port**: 8080
 - **Logging**: Comprehensive logging for all operations
+- **Notification Schedule**: Every 5 minutes (300,000 ms)
+- **Data Models**: Complete DTO structure for 3GPP compliance
+
+## Data Transfer Objects (DTOs)
+
+### Core DTOs
+- **SubscriptionRequestDTO**: Handles subscription requests with callback URI validation
+- **SubscriptionDTO**: Response object for subscription confirmation
+- **NotifyFileReadyDTO**: Complete notification payload sent to subscribers
+- **NotificationHeaderDTO**: Standard 3GPP notification header with metadata
+- **FileInfoDTO**: Detailed file information including location, size, and timestamps
+- **DateTimeDTO**: Standardized date/time format using ISO 8601
+
+### DTO Features
+- **Lombok Integration**: Automatic getter/setter generation and builder patterns
+- **Validation**: Jakarta validation annotations for request validation
+- **Builder Pattern**: Fluent API for object creation
+- **Sample Data**: Static factory methods for creating test data
+
+## Technical Architecture
+
+### Framework & Technology Stack
+- **Spring Boot 3.5.5** with Java 21
+- **Gradle** build system
+- **Lombok** for reducing boilerplate code
+- **Jakarta Validation** for request validation
+- **Spring Web** for REST API endpoints
+- **Spring Scheduling** for periodic notification tasks
+
+### Key Components
+- **FileDataReportingMnSController**: REST controller handling subscriptions and notifications
+- **Scheduled Notifications**: Automated file ready notifications every 5 minutes
+- **RestTemplate**: HTTP client for sending callback notifications
+- **In-memory Storage**: HashMap-based subscription management
+
+## Directory Structure
+
+```
+src/
+├── main/
+│   ├── java/org/oransc/ran/nssmf/simulator/
+│   │   ├── controller/
+│   │   │   └── FileDataReportingMnSController.java
+│   │   ├── dto/
+│   │   │   ├── DateTimeDTO.java
+│   │   │   ├── FileInfoDTO.java
+│   │   │   ├── NotificationHeaderDTO.java
+│   │   │   ├── NotifyFileReadyDTO.java
+│   │   │   ├── SubscriptionDTO.java
+│   │   │   └── SubscriptionRequestDTO.java
+│   │   └── RanNssmfSimulatorApplication.java
+│   └── resources/
+│       └── application.properties
+└── test/
+    └── java/org/oransc/ran_nssmf_simulator/
+```
+
+## Configuration
+
+### Application Properties
+- `spring.application.name=ran-nssmf-simulator`
+- `mns.fileDataReporting.version=v17.0.0`
+- `server.port=8080`
+- `spring.jackson.serialization.fail-on-empty-beans=false`
+
+### Build Configuration
+- **Java Version**: 21
+- **Spring Boot Version**: 3.5.5
+- **Dependency Management**: Spring Boot Gradle Plugin
+- **Testing**: JUnit 5 with Spring Boot Test
+
+## Deployment
+
+### Docker Support
+- **Dockerfile**: Contains instructions to build a Docker image for the Rapp
+- **Containerization**: Ready for deployment in containerized environments
+- **Port Exposure**: 8080 for HTTP access
+
+### Running the Application
+
+**Using Gradle:**
+```bash
+./gradlew bootRun
+```
+
+**Using Java:**
+```bash
+./gradlew build
+java -jar build/libs/ran-nssmf-simulator-0.0.1-SNAPSHOT.jar
+```
+
+**Using Docker:**
+```bash
+docker build -t ran-nssmf-simulator .
+docker run -p 8080:8080 ran-nssmf-simulator
+```
+
+## Testing and Integration
+
+### Health Checks
+- **Spring Boot Actuator**: Available for health monitoring
+- **Endpoint**: `http://localhost:8080/actuator/health`
+
+### Logging
+- **Comprehensive Logging**: All subscription and notification operations are logged
+- **Debug Information**: Detailed logs for troubleshooting integration issues
+- **Error Handling**: Graceful error handling for failed notifications
 
-Directory Structure
+## Use Cases
 
-src - contains source code for the Rapp
-Dockerfile - contains instructions to build a Docker image for the Rapp
+This simulator is designed to:
+1. **Test Integration**: Allow other RIC components to test NSSMF integration
+2. **Development Support**: Provide a mock NSSMF for development without real network equipment
+3. **Standard Compliance**: Demonstrate 3GPP 28.532 interface compliance
+4. **Callback Testing**: Enable testing of asynchronous notification mechanisms
+5. **Performance Testing**: Support load testing with multiple subscribers
+6. **API Validation**: Validate client implementations against 3GPP standards
index 273cdd0..b55d4cf 100644 (file)
@@ -3,16 +3,19 @@ package org.oransc.ran.nssmf.simulator.controller;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
+import org.oransc.ran.nssmf.simulator.dto.NotifyFileReadyDTO;
 import org.oransc.ran.nssmf.simulator.dto.SubscriptionDTO;
 import org.oransc.ran.nssmf.simulator.dto.SubscriptionRequestDTO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.ResponseEntity;
 import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.client.RestTemplate;
 
 import java.net.URI;
 import java.util.HashMap;
@@ -29,6 +32,9 @@ public class FileDataReportingMnSController {
     Map<Integer, SubscriptionRequestDTO> subscriptionMap = new HashMap<>();
     static int subscriptionId = 0;
 
+    private final RestTemplate restTemplate;
+
+
     @PostMapping("/subscriptions")
     public ResponseEntity<SubscriptionDTO> subscribe(HttpServletRequest httpRequest, @Valid @RequestBody SubscriptionRequestDTO request)
             throws Exception {
@@ -49,4 +55,27 @@ public class FileDataReportingMnSController {
         
         return ResponseEntity.created(location).body(subscriptionDTO);
     }
+
+    @Scheduled(fixedRate = 300000) // 15 minutes = 900,000 ms
+    public void sendFileReadyNotifications() {
+        logger.info("Starting to send file ready notifications to {} subscribers", subscriptionMap.size());
+
+        subscriptionMap.forEach((subscriptionId, subscription) -> {
+            try {
+                NotifyFileReadyDTO notification = NotifyFileReadyDTO.createSampleNotification();
+
+                ResponseEntity<String> response = restTemplate.postForEntity(
+                        subscription.getCallbackUri(),
+                        notification,
+                        String.class
+                );
+
+                logger.info("Successfully sent notification to subscription {} at {}. Response status: {}", subscriptionId, subscription.getCallbackUri(), response.getStatusCode());
+            } catch (Exception e) {
+                logger.error("Failed to send notification to subscription {} at {}. Error: {}", subscriptionId, subscription.getCallbackUri(), e.getMessage());
+            }
+        });
+
+        logger.info("Completed sending file ready notifications");
+    }
 }
diff --git a/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/DateTimeDTO.java b/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/DateTimeDTO.java
new file mode 100644 (file)
index 0000000..158a92b
--- /dev/null
@@ -0,0 +1,23 @@
+package org.oransc.ran.nssmf.simulator.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+public class DateTimeDTO {
+    private String dateTime;
+    
+    public static DateTimeDTO now() {
+        return DateTimeDTO.builder()
+                .dateTime(LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME))
+                .build();
+    }
+}
diff --git a/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/FileInfoDTO.java b/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/FileInfoDTO.java
new file mode 100644 (file)
index 0000000..de1367c
--- /dev/null
@@ -0,0 +1,36 @@
+package org.oransc.ran.nssmf.simulator.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+public class FileInfoDTO {
+    private String fileLocation;
+    private Integer fileSize;
+    private DateTimeDTO fileReadyTime;
+    private DateTimeDTO fileExpirationTime;
+    private String fileCompression;
+    private String fileFormat;
+    private String fileDataType;
+    private String jobId;
+    
+    public static FileInfoDTO createSampleFileInfo() {
+        return FileInfoDTO.builder()
+                .fileLocation("http://example.com/files/sample-performance-data-" + System.currentTimeMillis() + ".csv")
+                .fileSize(1024)
+                .fileReadyTime(DateTimeDTO.now())
+                .fileExpirationTime(DateTimeDTO.builder()
+                        .dateTime(java.time.LocalDateTime.now().plusHours(24).format(java.time.format.DateTimeFormatter.ISO_DATE_TIME))
+                        .build())
+                .fileCompression("gzip")
+                .fileFormat("CSV")
+                .fileDataType("Performance")
+                .jobId("job-" + System.currentTimeMillis())
+                .build();
+    }
+}
diff --git a/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotificationHeaderDTO.java b/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotificationHeaderDTO.java
new file mode 100644 (file)
index 0000000..9523107
--- /dev/null
@@ -0,0 +1,24 @@
+package org.oransc.ran.nssmf.simulator.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+public class NotificationHeaderDTO {
+    private String notificationId;
+    private String notificationType;
+    private DateTimeDTO eventTime;
+    
+    public static NotificationHeaderDTO createFileReadyHeader() {
+        return NotificationHeaderDTO.builder()
+                .notificationId("notif-" + System.currentTimeMillis())
+                .notificationType("notifyFileReady")
+                .eventTime(DateTimeDTO.now())
+                .build();
+    }
+}
diff --git a/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotifyFileReadyDTO.java b/sample-rapp-generator/rapp-ran-nssmf-simulator/ran-nssmf-simulator/src/main/java/org/oransc/ran/nssmf/simulator/dto/NotifyFileReadyDTO.java
new file mode 100644 (file)
index 0000000..2f0b262
--- /dev/null
@@ -0,0 +1,26 @@
+package org.oransc.ran.nssmf.simulator.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+@Data
+public class NotifyFileReadyDTO {
+    private NotificationHeaderDTO notificationHeader;
+    private List<FileInfoDTO> fileInfoList;
+    private String additionalText;
+    
+    public static NotifyFileReadyDTO createSampleNotification() {
+        return NotifyFileReadyDTO.builder()
+                .notificationHeader(NotificationHeaderDTO.createFileReadyHeader())
+                .fileInfoList(List.of(FileInfoDTO.createSampleFileInfo()))
+                .additionalText("Sample file ready notification from NSSMF simulator")
+                .build();
+    }
+}