Apache Axis2 OpenAPI Advanced Enterprise User Guide

Enterprise-Grade OpenAPI Integration - This advanced guide demonstrates the comprehensive OpenAPI capabilities introduced in Axis2 2.0.1, featuring enterprise-ready configuration management, modern authentication patterns including Bearer tokens and OAuth2, advanced security schemes, and sophisticated customization options. Perfect for building modern REST APIs that meet enterprise requirements for security, scalability, and developer experience.

New in Axis2 2.0.1: Complete enterprise-grade OpenAPI system with 40+ configuration options, multi-source configuration loading (properties files, system properties, environment variables), comprehensive security scheme integration (OAuth2, API Key, Bearer, Basic Auth), advanced SwaggerUI customization with 20+ options, OpenAPI customizer interface for post-processing, intelligent resource filtering, and performance optimizations.

This guide focuses on modern enterprise patterns including Bearer token authentication, OAuth2 integration, microservices architectures, cloud-native deployments, and developer-first API design principles. All examples use contemporary security and architectural patterns.

For legacy system integration patterns, see the Basic OpenAPI User Guide.

Introduction - Enterprise OpenAPI Architecture

Axis2's OpenAPI integration represents a complete enterprise-grade solution for REST API development, documentation, and management. Unlike basic API documentation tools, this system provides:

  • Configuration-Driven Architecture: 40+ configurable properties with multi-source loading
  • Enterprise Security: OAuth2, JWT Bearer tokens, API keys, and custom authentication schemes
  • Developer Experience: Advanced SwaggerUI with 20+ customization options
  • Extensibility: OpenAPI customizer interface for post-processing and enhancements
  • Performance: Intelligent caching, resource filtering, and optimization
  • Cloud-Native: Environment variable support, container-ready configuration

This guide assumes familiarity with modern REST API design, OAuth2/JWT authentication, and enterprise development patterns. All examples follow contemporary security and architectural practices.

Enterprise Configuration System

The Axis2 OpenAPI module provides a sophisticated configuration system supporting multiple sources and precedence levels, designed for enterprise deployment scenarios.

Configuration Sources and Precedence

Configuration is loaded from multiple sources in the following precedence order (highest to lowest):

  1. System Properties - JVM system properties (highest precedence)
  2. Environment Variables - OS environment variables
  3. Properties Files - Classpath properties files
  4. Module Parameters - axis2.xml module configuration
  5. Default Values - Built-in defaults (lowest precedence)

Properties File Configuration

Create openapi.properties in your classpath for comprehensive configuration:

# API Information
openapi.title=Financial Services API
openapi.description=Enterprise financial services with comprehensive security
openapi.version=2.1.0
openapi.contact.name=API Team
openapi.contact.email=api-team@company.com
openapi.contact.url=https://company.com/api-docs
openapi.license.name=Commercial License
openapi.license.url=https://company.com/license
openapi.termsOfServiceUrl=https://company.com/terms

# Security Configuration
openapi.security.oauth2.enabled=true
openapi.security.oauth2.authorizationUrl=https://auth.company.com/oauth2/authorize
openapi.security.oauth2.tokenUrl=https://auth.company.com/oauth2/token
openapi.security.oauth2.scopes=read:markets,write:trades,admin:users
openapi.security.apikey.enabled=true
openapi.security.apikey.name=X-API-Key
openapi.security.apikey.location=header

# Resource Filtering
openapi.readAllResources=false
openapi.resourcePackages=com.company.api.v2,com.company.services
openapi.resourceClasses=com.company.api.AuthController,com.company.api.TradeController
openapi.ignoredRoutes=/internal/.*,/health,/metrics

# Swagger UI Configuration
openapi.swaggerUi.enabled=true
openapi.swaggerUi.version=4.18.0
openapi.swaggerUi.deepLinking=true
openapi.swaggerUi.docExpansion=none
openapi.swaggerUi.filter=true
openapi.swaggerUi.customCss=/assets/custom-swagger.css
openapi.swaggerUi.customJs=/assets/custom-swagger.js

# Performance and Behavior
openapi.prettyPrint=false
openapi.useContextBasedConfig=true
openapi.scanKnownConfigLocations=true

Environment Variable Configuration

All properties can be overridden with environment variables for cloud deployments:

# Docker/Kubernetes environment variables
OPENAPI_TITLE="Production Financial API"
OPENAPI_SECURITY_OAUTH2_ENABLED=true
OPENAPI_SECURITY_OAUTH2_TOKEN_URL=https://prod-auth.company.com/oauth2/token
OPENAPI_SWAGGER_UI_ENABLED=false  # Disable UI in production
OPENAPI_RESOURCE_PACKAGES=com.company.api.prod

System Properties Configuration

Override any setting with JVM system properties:

java -Dopenapi.title="Development API" \
     -Dopenapi.security.oauth2.enabled=false \
     -Dopenapi.swaggerUi.enabled=true \
     -jar your-application.jar

Modern Authentication Patterns

The OpenAPI system supports modern authentication patterns including OAuth2, JWT Bearer tokens, and API keys with comprehensive security scheme integration.

Bearer Token Authentication (JWT)

Modern REST APIs use Bearer token authentication. Configure JWT Bearer tokens:

# properties configuration
openapi.security.bearer.enabled=true
openapi.security.bearer.format=JWT
openapi.security.bearer.description=JWT Bearer token authentication

Service implementation with Bearer authentication:

@Path("/api/v2")
@Tag(name = "Financial Services API v2", description = "Financial Services API v2")
public class FinancialServicesController {

    @POST
    @Path("/trades")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "Create new trade",
        description = "Create a new trade with Bearer token authentication",
        security = @SecurityRequirement(name = "bearerAuth")
    )
    @ApiResponses({
        @ApiResponse(responseCode = "201", description = "Trade created successfully"),
        @ApiResponse(responseCode = "401", description = "Unauthorized - invalid token"),
        @ApiResponse(responseCode = "403", description = "Forbidden - insufficient permissions")
    })
    public TradeResponse createTrade(
            @HeaderParam("Authorization") String bearerToken,
            @Parameter(description = "Trade details") @Valid TradeRequest request) {

        // Extract JWT token from Bearer header
        String jwt = extractJwtFromBearerHeader(bearerToken);

        // Validate JWT and extract user claims
        JwtClaims claims = jwtValidator.validateToken(jwt);
        UserContext userContext = UserContext.fromJwtClaims(claims);

        // Business logic with authenticated user context
        Trade trade = tradeService.createTrade(request, userContext);

        return TradeResponse.from(trade);
    }

    private String extractJwtFromBearerHeader(String bearerToken) {
        if (bearerToken == null || !bearerToken.startsWith("Bearer ")) {
            throw new UnauthorizedException("Invalid Bearer token format");
        }
        return bearerToken.substring(7);
    }
}

Client usage with Bearer tokens:

# Login to get JWT token
curl -X POST https://api.company.com/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"user@company.com","password":"secure123"}'

# Response:
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600,
  "scope": "read:trades write:trades"
}

# Use JWT token for API calls
curl -X POST https://api.company.com/api/v2/trades \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "symbol": "AAPL",
    "quantity": 100,
    "side": "BUY",
    "orderType": "MARKET"
  }'

OAuth2 Integration

Complete OAuth2 flow configuration for enterprise security:

# OAuth2 configuration
openapi.security.oauth2.enabled=true
openapi.security.oauth2.authorizationUrl=https://auth.company.com/oauth2/authorize
openapi.security.oauth2.tokenUrl=https://auth.company.com/oauth2/token
openapi.security.oauth2.refreshUrl=https://auth.company.com/oauth2/refresh
openapi.security.oauth2.scopes=read:markets,write:trades,admin:users,read:reports

OAuth2 service implementation:

@Path("/api/v2/reports")
@Tag(name = "Financial Reports API", description = "Financial Reports API")
public class ReportsController {

    @GET
    @Path("/portfolio/{portfolioId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "Get portfolio report",
        description = "Requires 'read:reports' scope",
        security = @SecurityRequirement(name = "oauth2", scopes = {"read:reports"})
    )
    public PortfolioReport getPortfolioReport(
            @HeaderParam("Authorization") String bearerToken,
            @PathParam("portfolioId") @Parameter(description = "Portfolio identifier") String portfolioId) {

        // Validate OAuth2 token and scopes
        OAuth2TokenInfo tokenInfo = oauth2Validator.validateToken(bearerToken);
        if (!tokenInfo.hasScope("read:reports")) {
            throw new ForbiddenException("Insufficient scope for reports access");
        }

        return reportsService.generatePortfolioReport(portfolioId, tokenInfo.getUserId());
    }
}

API Key Authentication

Enterprise API key management with flexible header configuration:

# API Key configuration
openapi.security.apikey.enabled=true
openapi.security.apikey.name=X-API-Key
openapi.security.apikey.location=header
openapi.security.apikey.description=Enterprise API key for programmatic access

Service with API key authentication:

@Path("/api/v2/market-data")
@Tag(name = "Market Data API", description = "Market Data API")
public class MarketDataController {

    @GET
    @Path("/quotes/{symbol}")
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "Get real-time quote",
        description = "Requires valid API key",
        security = @SecurityRequirement(name = "apiKeyAuth")
    )
    public QuoteResponse getQuote(
            @HeaderParam("X-API-Key") @Parameter(description = "API Key") String apiKey,
            @PathParam("symbol") @Parameter(description = "Stock symbol") String symbol) {

        // Validate API key and get associated permissions
        ApiKeyInfo keyInfo = apiKeyService.validateKey(apiKey);
        if (!keyInfo.hasMarketDataAccess()) {
            throw new ForbiddenException("API key does not have market data access");
        }

        Quote quote = marketDataService.getRealTimeQuote(symbol);
        return QuoteResponse.from(quote);
    }
}

Advanced Security Scheme Configuration

The OpenAPI system supports multiple simultaneous security schemes with sophisticated configuration options.

Multi-Security Scheme Setup

Configure multiple authentication methods for different API endpoints:

# Multiple security schemes configuration
openapi.security.bearer.enabled=true
openapi.security.bearer.format=JWT
openapi.security.bearer.description=JWT Bearer tokens for user authentication

openapi.security.apikey.enabled=true
openapi.security.apikey.name=X-API-Key
openapi.security.apikey.location=header
openapi.security.apikey.description=API keys for service-to-service communication

openapi.security.oauth2.enabled=true
openapi.security.oauth2.authorizationUrl=https://auth.company.com/oauth2/authorize
openapi.security.oauth2.tokenUrl=https://auth.company.com/oauth2/token
openapi.security.oauth2.scopes=read:data,write:data,admin:system

openapi.security.basic.enabled=false  # Disable basic auth for security

Programmatic Security Configuration

Advanced security setup using the OpenApiCustomizer interface:

@Component
public class SecuritySchemeCustomizer implements OpenApiCustomizer {

    @Override
    public void customize(OpenAPI openAPI) {
        // Add OAuth2 security scheme with detailed flow configuration
        SecurityScheme oauth2 = new SecurityScheme()
            .type(SecurityScheme.Type.OAUTH2)
            .description("OAuth2 authentication with PKCE support")
            .flows(new OAuthFlows()
                .authorizationCode(new OAuthFlow()
                    .authorizationUrl("https://auth.company.com/oauth2/authorize")
                    .tokenUrl("https://auth.company.com/oauth2/token")
                    .refreshUrl("https://auth.company.com/oauth2/refresh")
                    .scopes(createOAuth2Scopes())
                )
            );

        // Add JWT Bearer token scheme
        SecurityScheme bearerAuth = new SecurityScheme()
            .type(SecurityScheme.Type.HTTP)
            .scheme("bearer")
            .bearerFormat("JWT")
            .description("JWT Bearer token authentication");

        // Add enterprise API key scheme
        SecurityScheme apiKeyAuth = new SecurityScheme()
            .type(SecurityScheme.Type.APIKEY)
            .name("X-API-Key")
            .in(SecurityScheme.In.HEADER)
            .description("Enterprise API key for service authentication");

        // Register all security schemes
        openAPI.getComponents()
            .addSecuritySchemes("oauth2", oauth2)
            .addSecuritySchemes("bearerAuth", bearerAuth)
            .addSecuritySchemes("apiKeyAuth", apiKeyAuth);

        // Add global security requirements
        openAPI.addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
               .addSecurityItem(new SecurityRequirement().addList("apiKeyAuth"))
               .addSecurityItem(new SecurityRequirement().addList("oauth2"));
    }

    private Scopes createOAuth2Scopes() {
        return new Scopes()
            .addString("read:markets", "Read access to market data")
            .addString("write:trades", "Execute trades and orders")
            .addString("read:portfolio", "Read portfolio information")
            .addString("write:portfolio", "Modify portfolio settings")
            .addString("admin:users", "Administrative access to user management")
            .addString("admin:system", "System administration privileges");
    }

    @Override
    public int getPriority() {
        return 100; // High priority for security configuration
    }
}

Advanced SwaggerUI Customization

The OpenAPI system provides extensive SwaggerUI customization capabilities for enterprise branding and functionality.

Complete SwaggerUI Configuration

# Complete SwaggerUI customization
openapi.swaggerUi.enabled=true
openapi.swaggerUi.version=4.18.0

# UI Behavior Configuration
openapi.swaggerUi.deepLinking=true
openapi.swaggerUi.docExpansion=none
openapi.swaggerUi.filter=true
openapi.swaggerUi.displayOperationId=true
openapi.swaggerUi.displayRequestDuration=true
openapi.swaggerUi.defaultModelsExpandDepth=2
openapi.swaggerUi.defaultModelExpandDepth=2
openapi.swaggerUi.maxDisplayedTags=20

# Request/Response Configuration
openapi.swaggerUi.showRequestHeaders=true
openapi.swaggerUi.showResponseHeaders=true
openapi.swaggerUi.supportedSubmitMethods=get,post,put,delete,patch
openapi.swaggerUi.validatorUrl=https://validator.company.com/validator

# OAuth2 Configuration for SwaggerUI
openapi.swaggerUi.oauth2RedirectUrl=https://api.company.com/swagger-ui/oauth2-redirect.html
openapi.swaggerUi.oauth2ClientId=swagger-ui-client
openapi.swaggerUi.oauth2ClientSecret=swagger-ui-secret
openapi.swaggerUi.oauth2Realm=company-api
openapi.swaggerUi.oauth2AppName=Financial Services API

# Custom Styling
openapi.swaggerUi.customCss=/assets/corporate-swagger-theme.css
openapi.swaggerUi.customJs=/assets/swagger-enhancements.js

Corporate Branding with Custom CSS

Create corporate-themed SwaggerUI with custom CSS (/assets/corporate-swagger-theme.css):

/* Corporate theme for SwaggerUI */
.swagger-ui .topbar {
    background-color: #1e3a8a;
    border-bottom: 3px solid #3b82f6;
}

.swagger-ui .topbar .download-url-wrapper .select-label {
    color: #ffffff;
}

.swagger-ui .info .title {
    color: #1e3a8a;
    font-size: 2.5em;
    font-weight: 600;
}

.swagger-ui .info .description {
    font-size: 1.1em;
    line-height: 1.6;
    color: #4b5563;
}

/* Corporate header styling */
.corporate-header {
    background: linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%);
    color: white;
    padding: 20px;
    margin-bottom: 20px;
    border-radius: 8px;
}

.corporate-header h1 {
    margin: 0;
    font-size: 2em;
    font-weight: 600;
}

.corporate-header p {
    margin: 10px 0 0 0;
    opacity: 0.9;
    font-size: 1.1em;
}

/* Enhanced operation styling */
.swagger-ui .opblock.opblock-post {
    border-color: #059669;
    background: rgba(5, 150, 105, 0.1);
}

.swagger-ui .opblock.opblock-get {
    border-color: #0284c7;
    background: rgba(2, 132, 199, 0.1);
}

.swagger-ui .opblock.opblock-put {
    border-color: #ea580c;
    background: rgba(234, 88, 12, 0.1);
}

.swagger-ui .opblock.opblock-delete {
    border-color: #dc2626;
    background: rgba(220, 38, 38, 0.1);
}

/* Security badge styling */
.swagger-ui .auth-wrapper .authorize {
    background: #059669;
    border-color: #059669;
}

.swagger-ui .auth-wrapper .authorize:hover {
    background: #047857;
    border-color: #047857;
}

/* Enhanced model styling */
.swagger-ui .model-box {
    background: #f8fafc;
    border: 1px solid #e2e8f0;
    border-radius: 6px;
}

.swagger-ui .model .model-title {
    color: #1e3a8a;
    font-weight: 600;
}

Custom JavaScript Enhancements

Add advanced functionality with custom JavaScript (/assets/swagger-enhancements.js):

// Corporate SwaggerUI enhancements
window.addEventListener('load', function() {
    // Add corporate header
    const infoSection = document.querySelector('.swagger-ui .info');
    if (infoSection) {
        const corporateHeader = document.createElement('div');
        corporateHeader.className = 'corporate-header';
        corporateHeader.innerHTML = `
            

Financial Services API

Enterprise-grade financial services with comprehensive security and monitoring

Production Ready v2.1.0
`; infoSection.parentNode.insertBefore(corporateHeader, infoSection); } // Add authentication helper const authorizeButton = document.querySelector('.btn.authorize'); if (authorizeButton) { authorizeButton.addEventListener('click', function() { console.log('Authentication dialog opened'); // Add custom authentication logic here }); } // Enhanced error handling const originalFetch = window.fetch; window.fetch = function(...args) { return originalFetch.apply(this, args) .then(response => { if (response.status === 401) { showAuthenticationError(); } else if (response.status >= 500) { showServerError(); } return response; }) .catch(error => { showNetworkError(error); throw error; }); }; // Add helpful tooltips addCustomTooltips(); // Initialize performance monitoring initializePerformanceMonitoring(); }); function showAuthenticationError() { const notification = document.createElement('div'); notification.className = 'auth-error-notification'; notification.innerHTML = `
Authentication Required

Please authenticate using the Authorize button above

`; document.body.appendChild(notification); setTimeout(() => notification.remove(), 5000); } function showServerError() { console.warn('Server error detected - check API status'); } function showNetworkError(error) { console.error('Network error:', error); } function addCustomTooltips() { // Add tooltips to enhance user experience const operations = document.querySelectorAll('.opblock'); operations.forEach(op => { const method = op.querySelector('.opblock-summary-method'); if (method) { method.title = 'Click to expand operation details'; } }); } function initializePerformanceMonitoring() { // Monitor API response times const observer = new PerformanceObserver((list) => { list.getEntries().forEach((entry) => { if (entry.name.includes('/api/')) { console.log(`API Call: ${entry.name} - ${entry.duration.toFixed(2)}ms`); } }); }); observer.observe({entryTypes: ['navigation', 'resource']}); }

OpenAPI Customizer Interface

The OpenApiCustomizer interface provides powerful post-processing capabilities for advanced OpenAPI specification enhancement.

Advanced Customizer Implementation

@Component
@Order(100) // High priority
public class EnterpriseOpenApiCustomizer implements OpenApiCustomizer {

    private final ApiDocumentationService documentationService;
    private final SecurityConfigurationService securityService;

    @Override
    public void customize(OpenAPI openAPI) {
        // Enhanced API information
        enhanceApiInformation(openAPI);

        // Add enterprise security schemes
        configureEnterpriseSecuritySchemes(openAPI);

        // Add custom extensions
        addCustomExtensions(openAPI);

        // Configure advanced servers
        configureServers(openAPI);

        // Add comprehensive examples
        addComprehensiveExamples(openAPI);

        // Configure enterprise tags
        configureEnterpriseTags(openAPI);
    }

    private void enhanceApiInformation(OpenAPI openAPI) {
        Info info = openAPI.getInfo();

        // Add comprehensive contact information
        info.contact(new Contact()
            .name("API Development Team")
            .email("api-team@company.com")
            .url("https://company.com/api-support")
            .extensions(Map.of("x-team-slack", "#api-support"))
        );

        // Add detailed license information
        info.license(new License()
            .name("Commercial License")
            .url("https://company.com/api-license")
            .extensions(Map.of(
                "x-license-type", "commercial",
                "x-support-level", "enterprise"
            ))
        );

        // Add enterprise extensions
        info.addExtension("x-api-category", "financial-services");
        info.addExtension("x-compliance", Arrays.asList("SOC2", "PCI-DSS", "ISO27001"));
        info.addExtension("x-rate-limits", Map.of(
            "requests-per-minute", 1000,
            "burst-requests", 100
        ));
    }

    private void configureEnterpriseSecuritySchemes(OpenAPI openAPI) {
        Components components = openAPI.getComponents();

        // OAuth2 with multiple flows
        SecurityScheme oauth2 = new SecurityScheme()
            .type(SecurityScheme.Type.OAUTH2)
            .description("OAuth2 with PKCE support")
            .flows(new OAuthFlows()
                .authorizationCode(createAuthorizationCodeFlow())
                .clientCredentials(createClientCredentialsFlow())
            );

        // JWT Bearer with detailed configuration
        SecurityScheme jwtBearer = new SecurityScheme()
            .type(SecurityScheme.Type.HTTP)
            .scheme("bearer")
            .bearerFormat("JWT")
            .description("JWT Bearer tokens with RS256 signing")
            .addExtension("x-token-issuer", "https://auth.company.com")
            .addExtension("x-token-audience", "financial-api")
            .addExtension("x-token-expiry", "1h");

        // Enterprise API key
        SecurityScheme enterpriseApiKey = new SecurityScheme()
            .type(SecurityScheme.Type.APIKEY)
            .name("X-API-Key")
            .in(SecurityScheme.In.HEADER)
            .description("Enterprise API key with role-based permissions")
            .addExtension("x-key-rotation", "monthly")
            .addExtension("x-permissions-model", "rbac");

        components.addSecuritySchemes("oauth2", oauth2)
                  .addSecuritySchemes("jwtBearer", jwtBearer)
                  .addSecuritySchemes("enterpriseApiKey", enterpriseApiKey);
    }

    private OAuthFlow createAuthorizationCodeFlow() {
        return new OAuthFlow()
            .authorizationUrl("https://auth.company.com/oauth2/authorize")
            .tokenUrl("https://auth.company.com/oauth2/token")
            .refreshUrl("https://auth.company.com/oauth2/refresh")
            .scopes(createDetailedScopes())
            .addExtension("x-pkce-required", true)
            .addExtension("x-token-lifetime", "1h")
            .addExtension("x-refresh-token-lifetime", "30d");
    }

    private OAuthFlow createClientCredentialsFlow() {
        return new OAuthFlow()
            .tokenUrl("https://auth.company.com/oauth2/token")
            .scopes(createServiceScopes())
            .addExtension("x-client-authentication", "client_secret_jwt")
            .addExtension("x-token-lifetime", "1h");
    }

    private Scopes createDetailedScopes() {
        return new Scopes()
            .addString("read:profile", "Read user profile information")
            .addString("read:accounts", "Read account information and balances")
            .addString("read:transactions", "Read transaction history")
            .addString("write:trades", "Execute trades and manage orders")
            .addString("read:market-data", "Access real-time market data")
            .addString("write:portfolio", "Modify portfolio allocations")
            .addString("admin:users", "Manage user accounts and permissions")
            .addString("admin:system", "System administration privileges");
    }

    private void addCustomExtensions(OpenAPI openAPI) {
        // Add enterprise-specific extensions
        openAPI.addExtension("x-api-governance", Map.of(
            "owner", "financial-services-team",
            "lifecycle-stage", "production",
            "sla-tier", "gold"
        ));

        openAPI.addExtension("x-monitoring", Map.of(
            "health-check", "/health",
            "metrics", "/metrics",
            "traces", "distributed-tracing-enabled"
        ));

        openAPI.addExtension("x-documentation", Map.of(
            "guides", "https://docs.company.com/api/guides",
            "tutorials", "https://docs.company.com/api/tutorials",
            "changelog", "https://docs.company.com/api/changelog"
        ));
    }

    private void configureServers(OpenAPI openAPI) {
        openAPI.servers(Arrays.asList(
            new Server()
                .url("https://api.company.com")
                .description("Production environment")
                .addExtension("x-environment", "production")
                .addExtension("x-region", "us-east-1"),
            new Server()
                .url("https://staging-api.company.com")
                .description("Staging environment")
                .addExtension("x-environment", "staging")
                .addExtension("x-region", "us-east-1"),
            new Server()
                .url("https://dev-api.company.com")
                .description("Development environment")
                .addExtension("x-environment", "development")
                .addExtension("x-region", "us-west-2")
        ));
    }

    @Override
    public int getPriority() {
        return 100;
    }

    @Override
    public boolean shouldApply(OpenAPI openAPI) {
        // Only apply to production and staging environments
        String environment = System.getProperty("deployment.environment", "development");
        return Arrays.asList("production", "staging").contains(environment);
    }
}

Resource Management and Filtering

Advanced resource filtering and management capabilities for large-scale enterprise APIs.

Intelligent Resource Discovery

# Resource filtering configuration
openapi.readAllResources=false

# Package-based filtering
openapi.resourcePackages=com.company.api.v2,com.company.services.financial,com.company.auth

# Class-based filtering
openapi.resourceClasses=com.company.api.TradesController,com.company.api.PortfolioController

# Route exclusion patterns
openapi.ignoredRoutes=/internal/.*,/admin/.*,/health,/metrics,/actuator/.*

# Custom resource scanner
openapi.scannerClass=com.company.config.CustomResourceScanner

Custom Resource Scanner

@Component
public class CustomResourceScanner implements ResourceScanner {

    @Override
    public Set<Class<?>> scanForResources() {
        Set<Class<?>> resources = new HashSet<>();

        // Scan for annotated controllers
        resources.addAll(scanForAnnotatedControllers());

        // Scan for service interfaces
        resources.addAll(scanForServiceInterfaces());

        // Apply business rules for inclusion
        return resources.stream()
            .filter(this::shouldIncludeResource)
            .collect(Collectors.toSet());
    }

    private Set<Class<?>> scanForAnnotatedControllers() {
        // Custom logic for finding REST controllers
        return ClasspathScanner.scan("com.company.api")
            .filter(clazz -> clazz.isAnnotationPresent(Path.class))
            .filter(clazz -> clazz.isAnnotationPresent(Tag.class))
            .collect(Collectors.toSet());
    }

    private boolean shouldIncludeResource(Class<?> resource) {
        // Business logic for resource inclusion
        if (resource.isAnnotationPresent(InternalApi.class)) {
            return false; // Exclude internal APIs
        }

        if (resource.isAnnotationPresent(DeprecatedApi.class)) {
            DeprecatedApi deprecation = resource.getAnnotation(DeprecatedApi.class);
            return !deprecation.excludeFromDocs(); // Include unless explicitly excluded
        }

        // Include by default
        return true;
    }
}

Enterprise Integration Examples

Complete examples demonstrating modern enterprise patterns with comprehensive security and functionality.

Financial Trading API with Bearer Authentication

@Path("/api/v2/trading")
@Tag(name = "Trading API", description = "Enterprise trading services with comprehensive security")
@Component
public class TradingController {

    @Autowired
    private TradingService tradingService;

    @Autowired
    private JwtTokenValidator tokenValidator;

    @POST
    @Path("/orders")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "Place trading order",
        description = "Execute trading order with comprehensive validation and risk checks",
        security = @SecurityRequirement(name = "jwtBearer")
    )
    @ApiResponses({
        @ApiResponse(responseCode = "201", description = "Order placed successfully",
            content = @Content(schema = @Schema(implementation = OrderResponse.class))),
        @ApiResponse(responseCode = "400", description = "Invalid order parameters",
            content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
        @ApiResponse(responseCode = "401", description = "Authentication required",
            content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
        @ApiResponse(responseCode = "403", description = "Insufficient trading permissions",
            content = @Content(schema = @Schema(implementation = ErrorResponse.class))),
        @ApiResponse(responseCode = "429", description = "Rate limit exceeded",
            content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
    })
    public Response placeOrder(
            @HeaderParam("Authorization") @Parameter(description = "Bearer JWT token") String bearerToken,
            @Parameter(description = "Order details") @Valid OrderRequest orderRequest,
            @Context HttpServletRequest request) {

        try {
            // Extract and validate JWT token
            String jwt = extractJwtToken(bearerToken);
            JwtClaims claims = tokenValidator.validateToken(jwt);

            // Create user context with permissions
            UserContext userContext = UserContext.builder()
                .userId(claims.getSubject())
                .email(claims.getStringClaim("email"))
                .permissions(extractPermissions(claims))
                .sessionId(claims.getJwtId())
                .build();

            // Validate trading permissions
            validateTradingPermissions(userContext, orderRequest);

            // Execute order with risk management
            OrderResult result = tradingService.placeOrder(orderRequest, userContext);

            // Build comprehensive response
            OrderResponse response = OrderResponse.builder()
                .orderId(result.getOrderId())
                .status(result.getStatus())
                .executionPrice(result.getExecutionPrice())
                .executionTime(result.getExecutionTime())
                .commission(result.getCommission())
                .estimatedSettlement(result.getEstimatedSettlement())
                .riskMetrics(result.getRiskMetrics())
                .build();

            return Response
                .status(Response.Status.CREATED)
                .entity(response)
                .header("X-Order-Id", result.getOrderId())
                .header("X-Request-Id", generateRequestId())
                .build();

        } catch (InvalidTokenException e) {
            return createErrorResponse(Response.Status.UNAUTHORIZED, "INVALID_TOKEN", e.getMessage());
        } catch (InsufficientPermissionsException e) {
            return createErrorResponse(Response.Status.FORBIDDEN, "INSUFFICIENT_PERMISSIONS", e.getMessage());
        } catch (OrderValidationException e) {
            return createErrorResponse(Response.Status.BAD_REQUEST, "INVALID_ORDER", e.getMessage());
        } catch (RiskLimitExceededException e) {
            return createErrorResponse(Response.Status.BAD_REQUEST, "RISK_LIMIT_EXCEEDED", e.getMessage());
        }
    }

    @GET
    @Path("/orders/{orderId}")
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(
        summary = "Get order status",
        description = "Retrieve detailed order information and execution status",
        security = @SecurityRequirement(name = "jwtBearer")
    )
    public Response getOrderStatus(
            @HeaderParam("Authorization") String bearerToken,
            @PathParam("orderId") @Parameter(description = "Order identifier") String orderId) {

        String jwt = extractJwtToken(bearerToken);
        JwtClaims claims = tokenValidator.validateToken(jwt);
        UserContext userContext = createUserContext(claims);

        OrderStatus status = tradingService.getOrderStatus(orderId, userContext);
        OrderStatusResponse response = OrderStatusResponse.from(status);

        return Response.ok(response)
            .header("Cache-Control", "no-cache")
            .header("X-Request-Id", generateRequestId())
            .build();
    }

    private String extractJwtToken(String bearerToken) {
        if (bearerToken == null || !bearerToken.startsWith("Bearer ")) {
            throw new InvalidTokenException("Invalid Bearer token format");
        }
        return bearerToken.substring(7);
    }

    private Set<String> extractPermissions(JwtClaims claims) {
        try {
            return new HashSet<>(claims.getStringListClaim("permissions"));
        } catch (Exception e) {
            return Collections.emptySet();
        }
    }

    private void validateTradingPermissions(UserContext userContext, OrderRequest orderRequest) {
        if (!userContext.hasPermission("trade:execute")) {
            throw new InsufficientPermissionsException("Trading permission required");
        }

        if (orderRequest.getOrderValue() > 100000 && !userContext.hasPermission("trade:large_orders")) {
            throw new InsufficientPermissionsException("Large order permission required");
        }
    }

    private Response createErrorResponse(Response.Status status, String errorCode, String message) {
        ErrorResponse error = ErrorResponse.builder()
            .errorCode(errorCode)
            .message(message)
            .timestamp(Instant.now())
            .requestId(generateRequestId())
            .build();

        return Response.status(status)
            .entity(error)
            .header("X-Request-Id", error.getRequestId())
            .build();
    }

    private String generateRequestId() {
        return UUID.randomUUID().toString();
    }
}

Modern Request/Response Models

@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Trading order request with comprehensive validation")
public class OrderRequest {

    @NotNull(message = "Symbol is required")
    @Pattern(regexp = "[A-Z]{1,5}", message = "Invalid symbol format")
    @Schema(description = "Stock symbol", required = true, example = "AAPL")
    private String symbol;

    @NotNull(message = "Order side is required")
    @Schema(description = "Order side", required = true, allowableValues = {"BUY", "SELL"})
    private OrderSide side;

    @NotNull(message = "Quantity is required")
    @DecimalMin(value = "0.01", message = "Quantity must be positive")
    @Schema(description = "Order quantity", required = true, example = "100")
    private BigDecimal quantity;

    @NotNull(message = "Order type is required")
    @Schema(description = "Order type", required = true, allowableValues = {"MARKET", "LIMIT", "STOP", "STOP_LIMIT"})
    private OrderType orderType;

    @Schema(description = "Limit price (required for LIMIT and STOP_LIMIT orders)", example = "150.50")
    private BigDecimal limitPrice;

    @Schema(description = "Stop price (required for STOP and STOP_LIMIT orders)", example = "145.00")
    private BigDecimal stopPrice;

    @NotNull(message = "Time in force is required")
    @Schema(description = "Time in force", required = true, allowableValues = {"DAY", "GTC", "IOC", "FOK"})
    private TimeInForce timeInForce;

    @Schema(description = "Client order ID for tracking", example = "CLIENT-ORDER-123")
    private String clientOrderId;

    @Valid
    @Schema(description = "Additional order parameters")
    private OrderParameters parameters;

    // Constructors, getters, setters, builder pattern
}

@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Trading order response with execution details")
public class OrderResponse {

    @Schema(description = "Unique order identifier", example = "ORD-12345678")
    private String orderId;

    @Schema(description = "Current order status", allowableValues = {"PENDING", "FILLED", "PARTIALLY_FILLED", "CANCELLED", "REJECTED"})
    private OrderStatus status;

    @Schema(description = "Order submission timestamp", example = "2023-12-21T15:30:00Z")
    private Instant submissionTime;

    @Schema(description = "Execution price (if filled)", example = "150.25")
    private BigDecimal executionPrice;

    @Schema(description = "Filled quantity", example = "100")
    private BigDecimal filledQuantity;

    @Schema(description = "Remaining quantity", example = "0")
    private BigDecimal remainingQuantity;

    @Schema(description = "Commission charged", example = "0.99")
    private BigDecimal commission;

    @Schema(description = "Estimated settlement date", example = "2023-12-23")
    private LocalDate estimatedSettlement;

    @Valid
    @Schema(description = "Risk metrics for this order")
    private RiskMetrics riskMetrics;

    @Schema(description = "Execution venue", example = "NASDAQ")
    private String venue;

    // Constructors, getters, setters, builder pattern
}

@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(description = "Risk metrics and compliance information")
public class RiskMetrics {

    @Schema(description = "Position delta after execution", example = "0.15")
    private BigDecimal positionDelta;

    @Schema(description = "Portfolio value at risk", example = "25000.00")
    private BigDecimal valueAtRisk;

    @Schema(description = "Regulatory compliance status")
    private ComplianceStatus complianceStatus;

    @Schema(description = "Risk limit utilization percentage", example = "45.5")
    private BigDecimal riskUtilization;

    // Additional risk metrics...
}

Performance and Monitoring

Enterprise-grade performance optimization and monitoring capabilities for production deployments.

Performance Configuration

# Performance optimization settings
openapi.performance.caching.enabled=true
openapi.performance.caching.spec.ttl=300  # 5 minutes
openapi.performance.caching.ui.ttl=3600   # 1 hour

# Memory management
openapi.performance.streaming.enabled=true
openapi.performance.streaming.threshold=1048576  # 1MB

# Response compression
openapi.performance.compression.enabled=true
openapi.performance.compression.minSize=1024

# Connection pooling
openapi.performance.http.maxConnections=200
openapi.performance.http.connectionTimeout=5000
openapi.performance.http.readTimeout=30000

Monitoring and Observability

@Component
public class OpenApiMetricsCollector {

    private final MeterRegistry meterRegistry;
    private final Timer specGenerationTimer;
    private final Counter apiCallCounter;
    private final Gauge activeConnectionsGauge;

    public OpenApiMetricsCollector(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
        this.specGenerationTimer = Timer.builder("openapi.spec.generation.time")
            .description("Time taken to generate OpenAPI specification")
            .register(meterRegistry);

        this.apiCallCounter = Counter.builder("openapi.api.calls")
            .description("Total API calls processed")
            .register(meterRegistry);

        this.activeConnectionsGauge = Gauge.builder("openapi.connections.active")
            .description("Active connections to OpenAPI endpoints")
            .register(meterRegistry, this, OpenApiMetricsCollector::getActiveConnections);
    }

    public void recordSpecGeneration(Duration duration) {
        specGenerationTimer.record(duration);
    }

    public void recordApiCall(String endpoint, String method, int statusCode) {
        apiCallCounter.increment(
            Tags.of(
                "endpoint", endpoint,
                "method", method,
                "status", String.valueOf(statusCode)
            )
        );
    }

    private double getActiveConnections() {
        // Implementation to get active connections
        return 0.0;
    }
}

@Component
public class OpenApiHealthIndicator implements HealthIndicator {

    private final OpenApiSpecGenerator specGenerator;
    private final SwaggerUIHandler uiHandler;

    @Override
    public Health health() {
        try {
            // Check OpenAPI spec generation
            long startTime = System.currentTimeMillis();
            specGenerator.generateOpenApiSpec(null);
            long specGenTime = System.currentTimeMillis() - startTime;

            // Check SwaggerUI availability
            boolean uiAvailable = uiHandler.getConfiguration().isSupportSwaggerUi();

            return Health.up()
                .withDetail("specGenerationTime", specGenTime + "ms")
                .withDetail("swaggerUiEnabled", uiAvailable)
                .withDetail("version", "2.0.1")
                .withDetail("configurationSource", getConfigurationSource())
                .build();

        } catch (Exception e) {
            return Health.down()
                .withDetail("error", e.getMessage())
                .withException(e)
                .build();
        }
    }

    private String getConfigurationSource() {
        // Determine primary configuration source
        return "properties-file";
    }
}

Cloud-Native Deployment

Configuration and deployment patterns for cloud-native and containerized environments.

Docker Configuration

# Dockerfile
FROM openjdk:17-jre-slim

# Environment variables for OpenAPI configuration
ENV OPENAPI_TITLE="Financial Services API"
ENV OPENAPI_SECURITY_OAUTH2_ENABLED=true
ENV OPENAPI_SWAGGER_UI_ENABLED=false
ENV OPENAPI_RESOURCE_PACKAGES=com.company.api.v2

# Copy application
COPY target/financial-api.war /opt/axis2/webapps/
COPY config/openapi-production.properties /opt/axis2/conf/

EXPOSE 8080
CMD ["catalina.sh", "run"]

Kubernetes Configuration

apiVersion: v1
kind: ConfigMap
metadata:
  name: openapi-config
data:
  openapi.properties: |
    openapi.title=Financial Services API
    openapi.version=2.1.0
    openapi.security.oauth2.enabled=true
    openapi.security.oauth2.tokenUrl=https://auth.company.com/oauth2/token
    openapi.swaggerUi.enabled=false
    openapi.performance.caching.enabled=true
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: financial-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: financial-api
  template:
    metadata:
      labels:
        app: financial-api
    spec:
      containers:
      - name: api
        image: company/financial-api:2.1.0
        ports:
        - containerPort: 8080
        env:
        - name: OPENAPI_TITLE
          value: "Production Financial API"
        - name: OPENAPI_SECURITY_OAUTH2_TOKEN_URL
          valueFrom:
            secretKeyRef:
              name: oauth2-config
              key: token-url
        volumeMounts:
        - name: openapi-config
          mountPath: /opt/axis2/conf/openapi.properties
          subPath: openapi.properties
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /openapi.json
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: openapi-config
        configMap:
          name: openapi-config

Enterprise Security Best Practices

Comprehensive security guidelines for production OpenAPI deployments.

Production Security Checklist

  • ✓ JWT Token Validation: Implement proper JWT signature verification and expiration checking
  • ✓ OAuth2 PKCE: Enforce PKCE for public clients and authorization code flows
  • ✓ CORS Configuration: Restrict CORS origins to known domains in production
  • ✓ Rate Limiting: Implement rate limiting per API key/user to prevent abuse
  • ✓ Input Validation: Validate all request parameters against OpenAPI schemas
  • ✓ HTTPS Only: Enforce HTTPS for all API endpoints and disable HTTP
  • ✓ Security Headers: Include security headers (HSTS, CSP, X-Frame-Options)
  • ✓ API Key Rotation: Implement regular API key rotation policies
  • ✓ Audit Logging: Log all API access and authentication events
  • ✓ SwaggerUI Security: Disable SwaggerUI in production or restrict access

Security Configuration Example

# Production security configuration
openapi.security.enforceHttps=true
openapi.security.hsts.enabled=true
openapi.security.hsts.maxAge=31536000
openapi.security.csp.enabled=true
openapi.security.csp.policy=default-src 'self'; script-src 'self' 'unsafe-inline'

# Disable SwaggerUI in production
openapi.swaggerUi.enabled=false

# Restrict CORS to known origins
openapi.cors.allowedOrigins=https://app.company.com,https://mobile.company.com
openapi.cors.allowCredentials=true
openapi.cors.maxAge=3600

# Rate limiting
openapi.rateLimiting.enabled=true
openapi.rateLimiting.requestsPerMinute=100
openapi.rateLimiting.burstLimit=20

# Audit logging
openapi.audit.enabled=true
openapi.audit.logFormat=JSON
openapi.audit.includeRequestBody=false
openapi.audit.includeResponseBody=false

Troubleshooting and Advanced Topics

Common issues and advanced configuration scenarios for enterprise deployments.

Common Configuration Issues

  • Configuration Precedence: System properties override environment variables override properties files
  • Security Scheme Validation: Ensure OAuth2 endpoints are accessible and properly configured
  • Resource Filtering: Verify package names and class paths are correct
  • Memory Usage: Monitor memory usage with large OpenAPI specifications
  • Performance: Enable caching for frequently accessed specifications

Advanced Debugging

# Enable debug logging
logging.level.org.apache.axis2.openapi=DEBUG

# JVM debugging options
-Dopenapi.debug=true
-Dopenapi.performance.monitoring=true
-Dopenapi.configuration.trace=true

For comprehensive support and advanced enterprise deployment scenarios, contact the Apache Axis2 development team or consult the Basic OpenAPI User Guide for fundamental concepts.

This advanced guide demonstrates the full enterprise capabilities of Axis2's OpenAPI integration. The system provides the flexibility and power needed for modern enterprise API development while maintaining the reliability and performance expected in production environments.