### Maven Dependency Management Example Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Illustrates how core dependencies like Spring Boot, Spring Cloud, and Spring Cloud Alibaba are managed centrally in the `opensabre-base-dependencies` module. ```xml org.springframework.boot spring-boot-dependencies 3.4.1 pom import org.springframework.cloud spring-cloud-dependencies 2024.0.0 pom import com.alibaba.cloud spring-cloud-alibaba-dependencies 2023.0.3.2 pom import ``` -------------------------------- ### Build Project Modules with Maven Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Commands to build all modules of the Opensabre project using Maven. Includes options to clean, install, skip tests, and deploy to Maven Central. ```bash # Build all modules mvn clean install # Build with tests mvn clean install -DskipTests=false # Skip tests for faster builds mvn clean install -DskipTests=true # Deploy to Maven Central (requires deploy profile) mvn clean deploy -Pdeploy ``` -------------------------------- ### Adding a New Module to Parent POM Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Example of how to include a new module in the parent POM's `` section, which is a required step when adding new modules to the Opensabre project. ```xml pom opensabre-base-dependencies opensabre-web new-module-name ``` -------------------------------- ### Unified Response Format Example (Conceptual) Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Illustrates the standardized `Result` object structure used for all REST API responses in Opensabre. It includes fields for status code, message, timestamp, and the actual data payload. ```json { "code": "000000", "mesg": "Success message", "time": "2023-10-27T10:00:00Z", "data": { ... } } ``` -------------------------------- ### Exception Handling Hierarchy Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Shows the custom exception hierarchy in Opensabre, starting from `BaseException` and extending to `ServiceException`. It also references `ErrorType` and `SystemErrorType` for categorizing errors. ```java // Global exception handler advice // @ControllerAdvice // public class DefaultGlobalExceptionHandlerAdvice { ... } // Base custom exception public abstract class BaseException extends RuntimeException { } // Service-level exception public class ServiceException extends BaseException { } // Error type system // public interface ErrorType { ... } // public enum SystemErrorType implements ErrorType { ... } ``` -------------------------------- ### Run Tests with Maven Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Commands for executing tests within the Opensabre project using Maven. Supports running all tests, tests for a specific module, or a single test class. ```bash # Run all tests mvn test # Run tests for specific module cd opensabre-web && mvn test # Run single test class mvn test -Dtest=UserContextHolderTest ``` -------------------------------- ### Docker Image Building with Maven Plugins Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Specifies the Maven plugins used for Docker image building and containerization in Opensabre, including the Dockerfile Maven plugin and Jib Maven plugin, with a defined base image. ```xml com.spotify dockerfile-maven-plugin 1.4.13 com.google.cloud.tools jib-maven-plugin 3.4.0 eclipse-temurin:21-jre-alpine ``` -------------------------------- ### Global Exception Handling in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt Demonstrates how Opensabre automatically handles various exceptions by converting them into standardized `Result` responses. It also shows how to extend this functionality with a custom exception handler for `BusinessException`. ```java // Exceptions are automatically handled by DefaultGlobalExceptionHandlerAdvice // Validation errors (MethodArgumentNotValidException) // Request: POST /api/users with invalid body // Response: {"code":"020000","mesg":"Request parameter validation failed","data":"name cannot be empty"} // Missing parameters (MissingServletRequestParameterException) // Request: GET /api/users (missing required param) // Response: {"code":"020000","mesg":"Request parameter validation failed"} // Resource not found (NoHandlerFoundException) // Request: GET /api/nonexistent // Response: {"code":"000404","mesg":"Resource not found"} // Method not allowed (HttpRequestMethodNotSupportedException) // Request: DELETE /api/users (if only GET allowed) // Response: {"code":"020001","mesg":"Request method not supported"} // File upload size limit (MultipartException) // Response: {"code":"020010","mesg":"Uploaded file size exceeds limit"} // Custom BaseException // Response: {"code":"","mesg":""} // Unhandled exceptions // Response: {"code":"-1","mesg":"System exception"} // Custom exception handler extension @RestControllerAdvice @Order(Ordered.HIGHEST_PRECEDENCE) // Higher priority than default public class CustomExceptionHandlerAdvice { @ExceptionHandler(value = {BusinessException.class}) public Result handleBusinessException(BusinessException ex) { return Result.fail(ex.getErrorType(), ex.getData()); } } ``` -------------------------------- ### Generate Documentation and Flatten POM with Maven Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Maven commands for code quality tasks. Generates JavaDoc for the project and creates a flattened POM file, typically used for deployment. ```bash # Generate JavaDoc mvn javadoc:javadoc # Generate flattened POM (for deployment) mvn flatten:flatten ``` -------------------------------- ### Spring Boot Auto-Configuration Annotation Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Demonstrates the use of the `@AutoConfiguration` annotation for creating Spring Boot auto-configuration classes, a key practice when developing starter modules in Opensabre. ```java package com.opensabre.starter.example; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @AutoConfiguration @ConditionalOnClass(SomeClass.class) // Example condition public class ExampleAutoConfiguration { @Bean public ExampleService exampleService() { return new ExampleService(); } // Define other beans as needed } ``` -------------------------------- ### Service Communication with OpenFeign and Sentinel Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Highlights the use of OpenFeign for inter-service communication, including custom load balancing (`OpensabreLoadBalancer`), header propagation (`FeignHeaderInterceptor`), and Sentinel integration for resilience. ```java // Example OpenFeign client interface // @FeignClient(name = "some-service", configuration = FeignConfig.class) // public interface SomeServiceClient { ... } // Custom Load Balancer // public class OpensabreLoadBalancer implements LoadBalancerClient { ... } // Header Propagation // public class FeignHeaderInterceptor implements RequestInterceptor { ... } // Sentinel Integration (typically configured via properties or annotations) ``` -------------------------------- ### Unified REST Response Wrapper in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt Demonstrates the usage of the `Result` class for creating standardized REST API responses. It includes factory methods for success and failure scenarios, handling data, no data, and custom error types. This wrapper ensures consistent API output. ```java import io.github.opensabre.common.core.entity.vo.Result; import io.github.opensabre.common.core.exception.SystemErrorType; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/users") public class UserController { @GetMapping("/{id}") public Result getUser(@PathVariable String id) { // Success response with data UserVo user = userService.findById(id); return Result.success(user); // Response: {"code":"000000","mesg":"Processing successful","time":"2024-01-01T12:00:00.000Z","data":{...}} } @PostMapping public Result createUser(@RequestBody UserForm form) { userService.create(form); // Success response without data return Result.success(); // Response: {"code":"000000","mesg":"Processing successful","time":"2024-01-01T12:00:00.000Z"} } @DeleteMapping("/{id}") public Result deleteUser(@PathVariable String id) { try { userService.delete(id); return Result.success("User deleted"); } catch (Exception e) { // Failure response with error type return Result.fail(SystemErrorType.SYSTEM_ERROR); // Response: {"code":"-1","mesg":"System exception","time":"2024-01-01T12:00:00.000Z"} } } @PutMapping("/{id}") public Result updateUser(@PathVariable String id, @RequestBody UserForm form) { // Failure with specific error type and data if (!userService.exists(id)) { return Result.fail(SystemErrorType.RESOURCE_NOT_FOUND, "User not found: " + id); } userService.update(id, form); return Result.success(); } } ``` -------------------------------- ### Opensabre Maven Dependency Configuration Source: https://context7.com/opensabre/opensabre-framework/llms.txt Provides the necessary Maven dependencies to integrate various Opensabre framework modules into a Spring Boot project. This includes core components, web utilities, service registration, RPC, persistence, caching, configuration, event-driven architecture, and testing utilities. ```xml io.github.opensabre opensabre-base-dependencies 0.2.0 io.github.opensabre opensabre-starter-boot io.github.opensabre opensabre-web io.github.opensabre opensabre-starter-register io.github.opensabre opensabre-starter-rpc io.github.opensabre opensabre-starter-persistence io.github.opensabre opensabre-starter-cache io.github.opensabre opensabre-starter-config io.github.opensabre opensabre-starter-eda io.github.opensabre opensabre-test test ``` -------------------------------- ### Feign Client with Nacos Discovery and Fallback in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt Defines a Feign client interface for inter-service communication, integrating with Nacos for service discovery. Includes a fallback implementation for circuit breaker patterns to handle service unavailability gracefully. This requires Spring Cloud OpenFeign and Spring Cloud Alibaba Nacos Discovery dependencies. ```java // Feign client with service discovery @FeignClient(name = "user-service", fallback = UserClientFallback.class) public interface UserClient { @GetMapping("/api/users/{id}") Result getUser(@PathVariable("id") String id); @PostMapping("/api/users") Result createUser(@RequestBody UserForm form); } // Fallback implementation for circuit breaker @Component public class UserClientFallback implements UserClient { @Override public Result getUser(String id) { return Result.fail(SystemErrorType.GATEWAY_CONNECT_TIME_OUT); } @Override public Result createUser(UserForm form) { return Result.fail(SystemErrorType.GATEWAY_CONNECT_TIME_OUT); } } // Using the client @Service public class OrderService { @Autowired private UserClient userClient; public OrderVo createOrder(OrderForm form) { Result userResult = userClient.getUser(form.getUserId()); if (userResult.isFail()) { throw new BaseException(BusinessErrorType.USER_NOT_FOUND); } // Create order with user info return doCreateOrder(form, userResult.getData()); } } ``` -------------------------------- ### JetCache Configuration for Multi-Level Caching in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt Demonstrates configuring JetCache for multi-level caching with local (Caffeine) and remote (Redis) cache types. It shows how to define different TTLs and cache invalidation strategies using annotations. Dependencies include JetCache core and Caffeine/Redis cache implementations. ```java import com.alicp.jetcache.anno.*; import com.alicp.jetcache.Cache; @Service public class ProductService { // Default local cache (5 minutes) @Cached(name = "product:", key = "#id", cacheType = CacheType.LOCAL) public Product getProduct(String id) { return productRepository.findById(id); } // Long-time local cache (1 hour) @Cached(name = "category:", key = "#id", area = "longTime", cacheType = CacheType.LOCAL) public Category getCategory(String id) { return categoryRepository.findById(id); } // Short-time local cache (1 minute) - for time-sensitive data @Cached(name = "stock:", key = "#productId", area = "shortTime", cacheType = CacheType.LOCAL) public Integer getStock(String productId) { return inventoryRepository.getStock(productId); } // Default remote Redis cache (2 hours) @Cached(name = "user:profile:", key = "#userId", cacheType = CacheType.REMOTE) public UserProfile getUserProfile(String userId) { return userRepository.getProfile(userId); } // Long-time remote cache (12 hours) @Cached(name = "config:", key = "#key", area = "longTime", cacheType = CacheType.REMOTE) public String getConfig(String key) { return configRepository.getValue(key); } // Both local and remote (two-level cache) @Cached(name = "hot:product:", key = "#id", cacheType = CacheType.BOTH) public Product getHotProduct(String id) { return productRepository.findById(id); } // Cache invalidation @CacheInvalidate(name = "product:", key = "#product.id") public void updateProduct(Product product) { productRepository.save(product); } // Cache update @CacheUpdate(name = "product:", key = "#product.id", value = "#product") public Product saveProduct(Product product) { return productRepository.save(product); } } // Environment variables for Redis configuration: // REDIS_HOST=localhost // REDIS_PORT=6379 ``` -------------------------------- ### Maven Central Publishing Configuration Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Details the Maven plugin used for publishing artifacts to Maven Central (`central-publishing-maven-plugin`) and the requirement to activate the `deploy` profile for this process. ```xml io.github.gradle-nexus central-publishing-maven-plugin 0.4.2 true ``` -------------------------------- ### Manage Thread-Local User Context with UserContextHolder (Java) Source: https://context7.com/opensabre/opensabre-framework/llms.txt Illustrates using UserContextHolder for thread-safe access to user information. It shows how to set and clear the user context within a filter and how to retrieve user details in a service layer. ```java import io.github.opensabre.common.core.util.UserContextHolder; import java.util.Map; import java.util.HashMap; // Setting user context (typically done by interceptor) public class AuthenticationFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { Map userContext = new HashMap<>(); userContext.put("user_name", "johndoe"); userContext.put("user_id", "12345"); userContext.put("roles", "admin,user"); UserContextHolder.getInstance().setContext(userContext); try { chain.doFilter(req, res); } finally { // Always clear context after request UserContextHolder.getInstance().clear(); } } } // Accessing user context anywhere in the application @Service public class OrderService { public Order createOrder(OrderForm form) { // Get current username String username = UserContextHolder.getInstance().getUsername(); // Get full context map Map context = UserContextHolder.getInstance().getContext(); String userId = context.get("user_id"); String roles = context.get("roles"); Order order = new Order(); order.setCreatedBy(username); order.setUserId(userId); // ... return orderRepository.save(order); } } // UserInterceptor automatically sets context from gateway headers // Header: x-client-token-user: {"user_name":"johndoe","user_id":"12345"} ``` -------------------------------- ### Define User Entity and Related Forms/VOs with BasePo/BaseForm (Java) Source: https://context7.com/opensabre/opensabre-framework/llms.txt Demonstrates defining a User entity extending BasePo, along with UserVo, UserForm, UserQueryForm, and UserParam. These classes leverage BasePo and BaseForm for automatic audit field management and convenient conversion methods between different object types. ```java import io.github.opensabre.persistence.entity.po.BasePo; import io.github.opensabre.common.web.entity.vo.BaseVo; import io.github.opensabre.common.web.entity.form.BaseForm; import io.github.opensabre.persistence.entity.form.BaseQueryForm; import io.github.opensabre.persistence.entity.param.BaseParam; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; // Entity (PO) - extends BasePo for auto audit fields @Data @EqualsAndHashCode(callSuper = true) @TableName("t_user") public class User extends BasePo { private String name; private Integer age; private String email; private String mobile; } // Inherits: id, createdBy, createdTime, updatedBy, updatedTime // View Object (VO) @Data @EqualsAndHashCode(callSuper = true) public class UserVo extends BaseVo { private String name; private Integer age; private String email; } // Form for create/update operations @Data @EqualsAndHashCode(callSuper = true) public class UserForm extends BaseForm { private String name; private Integer age; private String email; private String mobile; } // Query form with pagination support @Data @EqualsAndHashCode(callSuper = true) public class UserQueryForm extends BaseQueryForm { private String name; private Integer minAge; private Integer maxAge; } // Query parameters @Data @EqualsAndHashCode(callSuper = true) public class UserParam extends BaseParam { private String name; private Integer minAge; private Integer maxAge; } // Usage in service/controller @Service public class UserService { @Autowired private UserMapper userMapper; public UserVo createUser(UserForm form) { // Convert form to entity (auto-mapping) User user = form.toPo(User.class); // createdBy, createdTime, updatedBy, updatedTime auto-filled on insert userMapper.insert(user); // Convert entity to VO return user.toVo(UserVo.class); } public Page queryUsers(UserQueryForm form) { // Get pagination parameters from form Page page = form.getPage(); // Convert form to query param UserParam param = form.toParam(UserParam.class); return userMapper.selectPage(page, buildWrapper(param)); } } ``` -------------------------------- ### Custom Exception Handling with BaseException and ErrorType in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt Illustrates how to define custom business error types using the `ErrorType` interface and `BaseException` class for standardized exception handling. This enables clear communication of business-specific errors with codes and messages, which are automatically caught by a global exception handler. ```java import io.github.opensabre.common.core.exception.BaseException; import io.github.opensabre.common.core.exception.ErrorType; import lombok.Getter; // Define custom error types @Getter public enum BusinessErrorType implements ErrorType { USER_NOT_FOUND("100001", "User not found"), USER_ALREADY_EXISTS("100002", "User already exists"), INVALID_CREDENTIALS("100003", "Invalid username or password"), PERMISSION_DENIED("100004", "Permission denied"); private final String code; private final String mesg; BusinessErrorType(String code, String mesg) { this.code = code; this.mesg = mesg; } } // Throw custom exceptions public class UserService { public User findById(String id) { User user = userRepository.findById(id); if (user == null) { throw new BaseException(BusinessErrorType.USER_NOT_FOUND, "User ID: " + id); } return user; } public void authenticate(String username, String password) { if (!isValidCredentials(username, password)) { throw new BaseException(BusinessErrorType.INVALID_CREDENTIALS); } } } // Global exception handler auto-catches BaseException // Returns: {"code":"100001","mesg":"User not found","time":"2024-01-01T12:00:00.000Z"} ``` -------------------------------- ### Nacos Service Registration and Discovery Configuration in YAML Source: https://context7.com/opensabre/opensabre-framework/llms.txt Configures Spring Cloud application for Nacos service registration and discovery. It enables discovery, sets the Nacos server address, and defines a cluster name based on environment variables for availability zone awareness. Requires Spring Cloud Alibaba Nacos Discovery dependency. ```yaml # application.yml - Service registration configuration spring: application: name: order-service cloud: nacos: discovery: enabled: true server-addr: ${REGISTER_HOST:localhost}:${REGISTER_PORT:8848} cluster-name: CLUSTER-${CLOUD_AZ:LOCAL} # Cluster based on availability zone # Environment variables: # REGISTER_HOST=nacos-server.example.com # REGISTER_PORT=8848 # CLOUD_AZ=SH # Results in cluster: CLUSTER-SH ``` -------------------------------- ### Base Entity Classes for Persistence and API Source: https://github.com/opensabre/opensabre-framework/blob/main/CLAUDE.md Defines the base classes for entities in Opensabre, including `BasePo` for persistence with audit fields, `BaseVo` for API responses, `BaseForm` for requests, and `BaseQueryForm` for search operations. ```java // Base persistence object with audit fields public abstract class BasePo { // createdBy, createdTime, updatedBy, updatedTime } // Base view object for API responses public abstract class BaseVo { } // Base form object for API requests public abstract class BaseForm { } // Base query form for search operations public abstract class BaseQueryForm { } ``` -------------------------------- ### Enable Audit Logging with @Audit Annotation in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt The @Audit annotation automatically logs details of controller method executions. It captures operation type, description, module, request/response data, and execution time. Enable this feature by annotating the main application class with @EnabledAudit. ```java import io.github.opensabre.boot.annotations.Audit; import io.github.opensabre.boot.annotations.EnabledAudit; import io.github.opensabre.boot.annotations.OperationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.*; // Enable audit functionality on main application class @SpringBootApplication @EnabledAudit public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @RestController @RequestMapping("/api/orders") public class OrderController { @PostMapping @Audit(operationType = OperationType.CREATE, description = "Create new order", module = "Order Management", request = true, response = true, key = "#form.orderId") // SpEL expression to extract key public Result createOrder(@RequestBody OrderForm form) { return Result.success(orderService.create(form)); } @PutMapping("/{id}") @Audit(operationType = OperationType.UPDATE, description = "Update order status", module = "Order Management", key = "#id") public Result updateOrder(@PathVariable String id, @RequestBody OrderForm form) { orderService.update(id, form); return Result.success(); } @DeleteMapping("/{id}") @Audit(operationType = OperationType.DELETE, description = "Delete order", module = "Order Management", request = true, response = false) public Result deleteOrder(@PathVariable String id) { orderService.delete(id); return Result.success(); } @GetMapping @Audit(operationType = OperationType.QUERY, description = "Query order list", module = "Order Management") public Result> listOrders(@RequestParam String status) { return Result.success(orderService.findByStatus(status)); } } // Operation types available: CREATE, UPDATE, DELETE, QUERY, LOGIN, LOGOUT, SCAN, EXPORT, IMPORT, DOWNLOAD, UPLOAD ``` -------------------------------- ### Mask Sensitive Data with @Desensitization Annotation in Java Source: https://context7.com/opensabre/opensabre-framework/llms.txt The @Desensitization annotation automatically masks sensitive fields in REST responses using predefined rules or custom patterns. It supports common types like mobile numbers, ID cards, and emails, as well as custom masking logic. ```java import io.github.opensabre.boot.annotations.Desensitization; import io.github.opensabre.boot.sensitive.rule.DefaultSensitiveRule; import lombok.Data; @Data public class UserProfileVo { private String id; private String username; // Mask mobile number: 138****1234 @Desensitization(type = DefaultSensitiveRule.MOBILE) private String mobile; // Mask ID card: 110101****1234 @Desensitization(type = DefaultSensitiveRule.ID_CARD) private String idCard; // Mask bank card: 6222****1234 @Desensitization(type = DefaultSensitiveRule.BANK_CARD) private String bankCard; // Mask email: ab***@example.com @Desensitization(type = DefaultSensitiveRule.EMAIL) private String email; // Mask name: 张* @Desensitization(type = DefaultSensitiveRule.NAME) private String realName; // Custom masking: keep first 3 and last 2 characters @Desensitization(type = DefaultSensitiveRule.CUSTOM, retainPrefixCount = 3, retainSuffixCount = 2, replaceChar = '*') private String accountNo; // Mask address: 上海市**区**** @Desensitization(type = DefaultSensitiveRule.ADDRESS) private String address; // Complete password masking @Desensitization(type = DefaultSensitiveRule.PASSWORD) private String password; } // REST response will automatically mask sensitive data: // { // "id": "123", // "username": "johndoe", // "mobile": "138****1234", // "idCard": "110101****1234", // "bankCard": "6222****1234", // "email": "jo***@example.com", // "realName": "张*", // "accountNo": "ACC***23", // "address": "上海市**区 ****", // "password": "******" // } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.