# AGENTS.md - RAIDGuard X Development Guide ## Project Overview RAIDGuard X is a Java 17 Swing desktop application for managing and monitoring RAID storage systems (by Accusys). **Location:** `RAIDGuardX/` **Main Entry Point:** `raidguard_x.AppMain` **Java Version:** 17 --- ## Build Commands ```bash # Navigate to project directory cd RAIDGuardX # Compile the project mvn compile # Run the application mvn compile exec:java -Dexec.mainClass="raidguard_x.AppMain" # Run with log output mvn compile exec:java -Dexec.mainClass="raidguard_x.AppMain" 2>&1 | tee RAIDGuardX_$(date +%Y%m%d_%H%M).log # Quick run (if already compiled) mvn exec:java -Dexec.mainClass="raidguard_x.AppMain" # Full clean build with packaging (creates macOS app) mvn clean package # Create JAR file only mvn jar:jar # Copy dependencies to target/dependency-libs mvn dependency:copy-dependencies # Run JAR directly java -cp "target/raidguard_x-1.0.562.jar:target/dependency-libs/*" raidguard_x.AppMain ``` ### Running Single Tests This project uses **JUnit 3.8.1** for testing. Test files are in `src/test/java/`. ```bash # Run all tests mvn test # Run a specific test class mvn test -Dtest=TestClassName # Run a specific test method mvn test -Dtest=TestClassName#testMethodName ``` --- ## Project Structure ``` src/main/java/raidguard_x/ ├── AppMain.java # Main entry point (applet/application) ├── frmMain.java # Main application window ├── InBandAPI/ # RAID controller communication (port 8922) │ ├── SendCmd.java # Command sending and protocol handling │ ├── BasePage.java # Base class for info pages │ ├── ControllerInfoPage.java │ ├── RAIDInfoPage.java │ └── ... ├── SNMP/ # SNMP trap implementation │ ├── SNMPSender.java │ ├── SNMPTrapSenderInterface.java │ ├── SNMPv1TrapPDU.java │ └── ... ├── Exception/ # Custom exceptions │ ├── AMEException.java │ └── ErrMsg.java ├── frm*.java # Form/dialog classes (JFrame) ├── dlg*.java # Dialog classes ├── jp*.java # JPanel classes ├── PageDataDB.java # Global data store ├── Langs.java # Localization support └── Debug.java # Logging utility ``` --- ## Code Style Guidelines ### General Conventions 1. **Indentation:** 4 spaces (no tabs) 2. **Braces:** Same-line style (K&R variant) ```java public class Example { public void method() { if (condition) { // code } } } ``` 3. **Line length:** No strict limit, but avoid excessive wrapping ### Naming Conventions | Element | Convention | Example | |---------|------------|---------| | Classes | PascalCase | `AppMain`, `SendCmd` | | Methods | camelCase | `sendPassword()`, `convetToAMEReplyFrame()` | | Variables | camelCase | `sIP`, `replyBuf`, `pageCode` | | Constants | UPPER_SNAKE | (rarely used) | | Packages | lowercase | `raidguard_x`, `exception` | **Prefix conventions observed in codebase:** - `s` prefix for Strings: `sIP`, `sSN`, `sVMVer` - `i` prefix for integers: `iCmdLen`, `iR` - `b`/`byte` for byte arrays: `byte[] replyBuf` ### Import Organization ```java package raidguard_x; import java.io.*; import java.net.*; import raidguard_x.*; import raidguard_x.Exception.*; ``` - Standard library imports first - Third-party imports second - Project imports last - Use wildcard imports for related packages (`java.io.*`, `java.net.*`) ### Error Handling - Use custom `AMEException` for protocol errors - Use `try-catch` blocks for I/O and network operations - Catch specific exceptions before generic ones - Always close resources in `finally` blocks ```java try { // network I/O code } catch (UnknownHostException ex) { System.err.println("Unknown host: " + ex.getMessage()); } catch (IOException ex) { System.err.println("IO error: " + ex.getMessage()); } catch (AMEException ex) { throw ex; } finally { try { if (socket != null) socket.close(); } catch (Exception e) { /* ignore */ } } ``` ### Logging/Debugging Use the `Debug` class for structured logging: ```java Debug.Log(">>> [Protocol] GET_PAGE: 0x%02X (%s)", pageCode, pageName); Debug.HexDump("RAW RECEIVED DATA", actualRead); ``` Avoid `System.out.println` for debug output (existing code may still use it). ### Swing/GUI Conventions 1. **EDT Compliance:** Use `SwingUtilities.invokeLater()` for UI updates ```java SwingUtilities.invokeLater(new Runnable() { public void run() { // UI code } }); ``` 2. **Platform Detection:** Use `AppMain.MAC_OS_X` and `AppMain.WIN` flags 3. **Font Settings:** Apply via `UIManager.put()` in `initGlobalFontSetting()` ### Comments - Use Javadoc for public classes and methods - Inline comments for non-obvious logic - Chinese comments present in original code for debugging sections ### Type Annotations - Use raw types sparingly (legacy codebase) - Avoid generic warnings when possible - Prefer `List`, `Map` over raw `ArrayList`, `HashMap` --- ## Dependencies | Library | Version | Purpose | |---------|---------|---------| | JUnit | 3.8.1 | Testing | | javax.mail | 1.6.2 | Email functionality | | org.json | 20231013 | JSON parsing | --- ## Key Protocols ### In-Band API (Port 8922) Protocol for communicating with RAID controllers: - OpCode 0x01: GET_PAGE (read info pages) - OpCode 0x1D: SEND_PASSWORD - OpCode 0xBC: Unlock - OpCode 0x1B: Erase RAID - OpCode 0xCC: Create RAID - OpCode 0xCE: Set Global Config - OpCode 0x26: Commit Configuration ### SNMP Custom SNMP implementation supporting v1 and v2 traps for event notification. --- ## Development Notes 1. **Java 17 Required:** Set `17` in pom.xml 2. **macOS Considerations:** Set `apple.laf.useScreenMenuBar=true` for menu bar 3. **Socket Timeout:** Default 3 seconds (prevent hangs on network issues) 4. **DEXT Service:** C++ service must be running on port 8922 for full functionality