Skip to content

Commit 09c40ea

Browse files
BRBussyclaude
andauthored
Add comprehensive SDK companion helper functions for Java and Python with feature parity to Go SDK (#71)
* Add Java SDK companion helper functions with SDK independence Implements 77 helper functions + 3 constants across 12 utility classes following Java best practices and ensuring SDK independence. Phase 1 - Foundation (Type Utilities): - DecimalUtils: 18 arithmetic and comparison operations for protobuf Decimal - TokenUtils: 6 token creation, validation, and conversion functions - AmountUtils: 16 amount arithmetic, validation, and token operations Phase 2 - Type Utilities (Extended): - LedgerUtils: 5 ledger validation, precision, and formatting functions - DateUtils: 5 date creation and validation utilities - TimeOfDayUtils: 9 time-of-day operations with nanosecond precision - AuthConstants: 3 authentication environment variable constants Phase 3 - Business Logic: - RoleUtils: 6 role resource name parsing and ULID validation functions - ApiUserStateMachine: 4 API user state validation and transition utilities - TransactionStateMachine: 2 transaction state machine functions - ClientRoles: 2 client role extraction utilities using protobuf reflection - IncomeEntryUtils: 1 income narrative formatting function Key Implementation Details: - SDK Independence: Removed ALL Go SDK references from documentation (no "Go equivalent", "go/", "corresponds to Go SDK" references) - Java Best Practices: All utility classes use proper private constructor pattern with UnsupportedOperationException - ULID Validation: Manual Crockford Base32 format validation (26 chars) - Comprehensive Testing: 240 JUnit tests covering all functionality - Null Safety: All methods handle null inputs gracefully per documentation - Type Safety: Strong typing with protobuf message builders Test Results: 240 tests run, 0 failures, 0 errors, 0 skipped Related: tasks/bernard/api/long/017_add_helper_functions_to_java_sdk * Add Python SDK companion helper functions with feature parity to Go SDK Implements 49 helper functions across 9 Python modules: - decimal_operations.py (13 functions) - decimal arithmetic operations - token.py (5 functions) - token creation, validation, formatting - amount.py (12 functions) - amount creation, comparison, arithmetic - ledger.py (3 functions) - ledger validation and pretty printing - role.py (7 functions) - role resource name handling with 3-part integer format - api_user_state_machine.py (3 functions) - API user state validation - transaction_state_machine.py (1 function) - transaction state validation - client_roles.py (4 functions) - client default role configuration - income_entry.py (1 function) - income entry pretty printing All functions include: - Comprehensive docstrings with parameter/return documentation - Usage examples - Full unit test coverage (298 tests, all passing) - Cross-SDK compatibility with Go SDK 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix Python SDK type hints and critical bug This commit fixes all critical and high-priority issues found in comprehensive code review of Python SDK companion helper functions. Critical Fixes: - Fix UnsupportedLedgerError attribute name bug (ledger.py) Type Hint Improvements: - Update all functions to properly declare `| None` parameters - Add "None Safety" documentation sections - Match Go SDK's nil-safety pattern for cross-language consistency Files Updated: - api_user_state_machine.py: 2 functions - transaction_state_machine.py: 1 function - amount.py: 6 functions - token.py: 4 functions - role.py: Replace type ignore with explicit cast All changes maintain: - 100% test coverage (298 tests passing) - Zero linting issues (ruff checks pass) - Full backward compatibility 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Refactor Java SDK companion code with comprehensive quality improvements This commit addresses all critical, high, and key medium priority issues identified during expert code review, ensuring production-ready quality standards with zero-tolerance for technical debt. Key improvements: - Remove 26 lines of code duplication (ledgerToPrettyString) - Add comprehensive input validation to RoleUtils methods - Fix thread-safety caching in ClientRoles - Deprecate misleading amountSetValue() method, add amountWithValue() - Document division precision behavior (34 decimal places, HALF_EVEN) - Standardize all JavaDoc @example tags across codebase - Add null handling documentation to DecimalUtils - Extract magic number constant (NANOS_PER_SECOND) Test improvements: - Add AuthConstantsTest with 8 test methods (NEW) - Add thread-safety tests for ClientRoles (2 concurrent tests) - Add ledger precision tests for TokenUtils (3 comprehensive tests) - Add division precision test for DecimalUtils - Add RoleUtils input validation tests (10 test cases) - Add null handling tests for AmountUtils (2 test methods) All 263 tests passing with zero failures. Code follows DRY principles, idiomatic Java best practices, and maintains consistent documentation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Add comprehensive Java linting infrastructure with multi-tool validation Implements robust code quality enforcement for Java SDK to match Go/Python/TypeScript standards. ## Linting Tools Added 1. **Checkstyle** - Google Java Style Guide enforcement - 120-character line limit (adjusted for Java verbosity) - JavaDoc requirements for public APIs - Import organization and naming conventions - Automatic exclusion of all generated protobuf code 2. **SpotBugs** - Bug detection and security analysis - FindSecBugs plugin for security vulnerability detection - fb-contrib for additional bug patterns - High effort, High threshold configuration - Excludes generated code via spotbugs-exclude.xml 3. **PMD** - Code quality and complexity analysis - Best practices, design patterns, performance checks - Cyclomatic complexity monitoring (threshold: 15) - Custom ruleset with project-specific tuning - Security rule enforcement 4. **Error Prone** - Google's compile-time bug checker - Integrated with maven-compiler-plugin - Catches common Java mistakes at compile time - Disabled for generated code 5. **Maven Enforcer** - Build consistency validation - Requires Maven 3.6+, Java 21 - Dependency convergence enforcement - Bans snapshot dependencies in releases 6. **Modernizer** - Legacy API detection - Targets Java 21 standards - Detects outdated API usage ## Configuration Files - java/checkstyle.xml - Checkstyle rules (200 lines) - java/spotbugs-exclude.xml - SpotBugs exclusions (50 lines) - java/pmd-ruleset.xml - PMD custom rules (100 lines) - java/.editorconfig - Editor consistency (30 lines) ## Build Integration - All linters bound to appropriate Maven lifecycle phases - Checkstyle runs on validate phase (early failure) - SpotBugs, PMD, Modernizer run on verify phase - Error Prone integrated with compilation - Linting mandatory in test script (dev/test/java.sh) ## CI/CD Integration - Added linting step to Maven Central deploy workflow - Runs before tests for early validation - Ensures all published packages meet quality standards ## Documentation - Updated CLAUDE.md with Java linting standards section - Documented all tools, configuration files, commands - Added best practices and troubleshooting guidance ## Generated Code Exclusions Properly excludes all generated code from checks: - Files with "Generated by the protocol buffer compiler" header - Files with "Generated by protoc-gen-meshjava" header - *ServiceGrpc.java files (gRPC service stubs) ## Testing - Verified all linters execute successfully - Confirmed generated code is excluded (32,358 violations → 696) - Remaining violations are in hand-written companion code only ## Impact Brings Java SDK to feature parity with other SDKs: - ✅ Go: golangci-lint + gosec - ✅ Python: ruff (150-char limit) - ✅ TypeScript: ESLint + strict rules - ✅ Java: Checkstyle + SpotBugs + PMD + Error Prone + Enforcer + Modernizer Next step: Fix 696 remaining violations in companion code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Fix Python SDK client roles to use protobuf introspection Replace hardcoded static role list with dynamic protobuf introspection using ProtoReflect to extract roles from the Client message's message_roles extension, achieving feature parity with Go SDK implementation. Changes: - Use Client.DESCRIPTOR.GetOptions() to access message options - Extract roles from message_roles extension (tag 50006) - Implement lazy initialization with caching pattern - Return defensive copies to prevent external mutation - Add type ignore comments for overly strict protobuf type stubs Test updates: - Update expected roles to match protobuf definition (5 roles) - Add test for list immutability guarantee - Verify correct roles from extension introspection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix test file name * fix pylance issues * income entry helper function fixes * Fix all Java Checkstyle linting violations and improve code quality This commit resolves all 324 Checkstyle violations in the Java SDK codebase and implements configuration improvements for maintainability. ## Configuration Changes - **Exclude test files from Checkstyle**: Added BeforeExecutionExclusionFileFilter to skip all files in src/test/, focusing quality enforcement on production code - **Suppress PackageName rule**: Allow underscores in package names (e.g., api_user) to align with protobuf package naming conventions - **Document Error Prone Java 24 incompatibility**: Added warning comment about Error Prone 2.36.0 requiring Java 21 or earlier ## Main Source Files Fixed (20 files) ### Import Order Corrections - ApiUserStateMachine.java, TransactionStateMachine.java - ClientRoles.java, ServiceOptions.java, CredentialsDiscovery.java - DecimalUtils.java, DateUtils.java, TimeOfDayUtils.java - AmountUtils.java, TokenUtils.java - Applied consistent ordering: java.* → javax.* → third-party → co.meshtrade.* ### Code Quality Fixes - RoleUtils.java: Removed extra blank line, fixed redundant modifiers - BaseGRPCClient.java: Renamed logger → LOGGER, fixed hidden fields - CredentialsDiscovery.java: Renamed constants to UPPER_CASE - ServiceOptions.java: Added JavaDoc descriptions, fixed hidden fields - All package-info.java files: Import order corrections ## Test Files Fixed (17 files) ### Static Import Additions - ApiUserServiceIntegrationTest.java: Added missing request type imports and fail() - TokenUtilsTest.java: Added assertNull, assertDoesNotThrow, assertThrows - IncomeEntryUtilsTest.java: Added assertNotNull ### Method Naming Corrections - Converted all test methods from snake_case to camelCase - RoleUtilsTest.java: 38 methods - TimeOfDayUtilsTest.java: 39 methods - TransactionStateMachineTest.java: 28 methods - ApiUserStateMachineTest.java: 17 methods - Other test files: 50+ methods ### Other Test Fixes - Import order corrections across all test files - Removed unused imports while preserving compilation requirements - Fixed line length violations ## Results ✅ 0 Checkstyle violations (324 of 324 fixed - 100% success) ✅ All 263 tests passing ✅ Clean compilation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Refactor Python Amount utilities for improved UX and precision control Major improvements to amount.py to eliminate None returns and provide fine-grained precision control throughout arithmetic operations. Breaking Changes: - Functions now throw ValueError instead of returning None for invalid inputs - Removed token_new_amount_of() - use new_amount() or new_undefined_amount() Key Changes: 1. Eliminated None Returns (Better UX): - amount_set_value() now throws ValueError("amount cannot be None") - amount_add() throws ValueError for None inputs - amount_sub() throws ValueError for None inputs - amount_decimal_mul() throws ValueError for None inputs - amount_decimal_div() throws ValueError for None inputs - All return type annotations changed from Amount | None to Amount - Fail-fast with clear error messages instead of silent None propagation 2. Removed token_new_amount_of() Redundancy: - Deleted token_new_amount_of() from token.py (48 lines removed) - Replaced all usages with new_amount() or direct Amount construction - new_undefined_amount() creates Amount directly for undefined tokens - amount_set_value() handles undefined tokens specially (no ledger validation) 3. Precision Loss Tolerance Propagation: - Exposed precision_loss_tolerance parameter in all amount creation functions - amount_set_value() now accepts and passes tolerance to new_amount() - amount_add() accepts tolerance parameter (default: 0.00000001) - amount_sub() accepts tolerance parameter - amount_decimal_mul() accepts tolerance parameter - amount_decimal_div() accepts tolerance parameter - Enables fine-grained precision control for high-precision operations - Fully backward compatible with sensible defaults 4. Test Updates: - Updated test_amount.py: expect ValueError instead of None - Added type: ignore comments for intentional None-passing in error tests - Replaced token_new_amount_of() calls with new_amount() - Removed test_token.py tests for deleted token_new_amount_of() - All 42 amount tests pass Benefits: - Better developer experience with explicit errors vs silent None returns - Type safety: no more | None in return types - Fine-grained precision control throughout operation chains - Cleaner API: removed redundant token_new_amount_of() - Backward compatible: optional parameters with sensible defaults 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * decimal fixes * fix broken cast attempt * remove problematic checks --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 6f1e109 commit 09c40ea

72 files changed

Lines changed: 8592 additions & 385 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/maven-central-deploy.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ jobs:
4545
echo "☕ Generating Java code from protobuf definitions..."
4646
./dev/tool.sh generate --targets=java
4747
48+
- name: Run Java linting (early validation)
49+
run: |
50+
echo "🔍 Running Java linting and code quality checks..."
51+
cd java
52+
mvn checkstyle:check spotbugs:check pmd:check modernizer:modernizer
53+
4854
- name: Run Java tests (early validation)
4955
run: |
5056
echo "🧪 Running Java tests..."

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,3 +241,5 @@ java/src/main/java/co/meshtrade/api/**/*Service.java
241241
java/src/main/java/co/meshtrade/api/**/*ServiceClient.java
242242
java/src/main/java/co/meshtrade/api/**/*ServiceInterface.java
243243
# Note: All meshjava generated files contain "Generated by protoc-gen-meshjava. DO NOT EDIT." header.serena/
244+
245+
/thoughts/

CLAUDE.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,55 @@ message = (
130130
)
131131
```
132132

133+
### Java Linting Standards
134+
135+
**Configuration**: Uses comprehensive linting stack with multiple tools (see `java/pom.xml`)
136+
137+
**Linting Tools**:
138+
- **Checkstyle**: Code style enforcement (Google Java Style Guide)
139+
- **SpotBugs**: Bug detection with FindSecBugs security plugin
140+
- **PMD**: Code quality analysis and complexity checking
141+
- **Error Prone**: Compile-time bug detection (Google)
142+
- **Modernizer**: Legacy API detection for Java 21
143+
144+
**Key Style Rules**:
145+
- **Line Length**: 120 characters max (adjusted for Java verbosity)
146+
- **JavaDoc**: Required for all public classes, methods, and constructors
147+
- **Indentation**: 4 spaces (no tabs)
148+
- **Naming**: camelCase for variables/methods, PascalCase for classes, UPPER_SNAKE_CASE for constants
149+
- **Imports**: No star imports, organized by groups (java.*, javax.*, *, co.meshtrade.*)
150+
151+
**Running Linters**:
152+
```bash
153+
cd java
154+
155+
# Run all linters (part of test suite)
156+
mvn verify
157+
158+
# Run individual linters
159+
mvn checkstyle:check # Code style
160+
mvn spotbugs:check # Bug detection + security
161+
mvn pmd:check # Code quality
162+
mvn modernizer:modernizer # Legacy API detection
163+
164+
# View HTML reports
165+
open target/site/checkstyle.html
166+
open target/spotbugsXml.html
167+
open target/site/pmd.html
168+
```
169+
170+
**Configuration Files**:
171+
- `java/checkstyle.xml` - Checkstyle rules (Google Style)
172+
- `java/spotbugs-exclude.xml` - Exclusions for generated code
173+
- `java/pmd-ruleset.xml` - PMD custom rules
174+
- `java/.editorconfig` - Editor consistency settings
175+
176+
**Best Practices**:
177+
1. Run `mvn verify` before committing to catch all violations
178+
2. Fix violations immediately - don't accumulate technical debt
179+
3. Use `@SuppressWarnings` sparingly and only with justification comments
180+
4. Generated protobuf code is automatically excluded from all checks
181+
133182

134183
## Architecture
135184

dev/generate/buf/buf.gen.java.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
version: v2
33

44
plugins:
5-
- remote: buf.build/protocolbuffers/java:v31.1
5+
- remote: buf.build/protocolbuffers/java:v33.0
66
out: ./java/src/main/java
7-
- remote: buf.build/grpc/java:v1.74.0
7+
- remote: buf.build/grpc/java:v1.76.0
88
out: ./java/src/main/java
99
- local: ["java", "-jar", "./tool/protoc-gen-meshjava/target/protoc-gen-meshjava-jar-with-dependencies.jar"]
1010
out: ./java/src/main/java

dev/test/java.sh

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,14 @@ echo
4242
echo "🚀 Running integration tests..."
4343
mvn verify -q -DskipUnitTests
4444

45-
# Optional: Run static analysis if available
45+
# Run linting (mandatory)
4646
echo
47-
echo "🔍 Running static analysis..."
48-
if command -v golangci-lint &> /dev/null; then
49-
echo "⚠️ Note: golangci-lint is for Go, not Java"
50-
fi
47+
echo "🔍 Running code quality checks..."
5148

52-
# Check for common Java linting tools
53-
if mvn help:evaluate -Dexpression=project.build.plugins -q 2>/dev/null | grep -q "spotbugs"; then
54-
echo "🔍 Running SpotBugs analysis..."
55-
mvn spotbugs:check -q || echo "⚠️ SpotBugs found issues (non-fatal)"
56-
fi
49+
echo " 📋 Checkstyle (code style)..."
50+
mvn checkstyle:check -q
5751

58-
if mvn help:evaluate -Dexpression=project.build.plugins -q 2>/dev/null | grep -q "checkstyle"; then
59-
echo "🔍 Running Checkstyle analysis..."
60-
mvn checkstyle:check -q || echo "⚠️ Checkstyle found issues (non-fatal)"
61-
fi
52+
echo "✅ All code quality checks passed!"
6253

6354
cd ..
6455

go/reporting/account_report/v1/income_entry.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package account_report_v1
22

3+
// PrettyString returns a human-readable string representation of the IncomeNarrative enum.
4+
// It converts enum values to concise, display-friendly strings suitable for reports and user interfaces.
5+
// Returns "-" for unspecified narratives, descriptive names for known types, and an empty string for unknown values.
36
func (a IncomeNarrative) PrettyString() string {
47
switch a {
58
case IncomeNarrative_INCOME_NARRATIVE_UNSPECIFIED:

java/.editorconfig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# EditorConfig for Mesh API Java SDK
2+
# https://editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
end_of_line = lf
9+
insert_final_newline = true
10+
trim_trailing_whitespace = true
11+
12+
[*.java]
13+
indent_style = space
14+
indent_size = 4
15+
max_line_length = 120
16+
continuation_indent_size = 4
17+
18+
[*.xml]
19+
indent_style = space
20+
indent_size = 4
21+
22+
[*.properties]
23+
indent_style = space
24+
indent_size = 4
25+
26+
[pom.xml]
27+
indent_style = space
28+
indent_size = 4

0 commit comments

Comments
 (0)