Skip to main content

Connection Management

Learn how ConstellationAPI manages connections in a multi-tenant environment with automatic connection pooling and reuse.

Overview

ConstellationAPI implements tenant-aware connection pooling that automatically manages connections to external services (Jira, GitHub, etc.) for each tenant. This ensures:

  • Tenant Isolation: Each company has completely separate connections
  • Connection Reuse: Connections are cached and reused across requests
  • Performance: Reduced latency by avoiding connection creation overhead
  • Automatic Management: Connections are created, cached, and expired automatically

How It Works

Connection Lifecycle

1. Request arrives with JWT token

2. Extract tenant_id and connection config from JWT

3. Generate connection hash from config

4. Check Redis cache: constellation:connection:{tenant_id}:{type}:{hash}

5a. Cache HIT → Reuse existing connection (fast)
5b. Cache MISS → Create new connection → Cache it

6. Use connection for API call

7. Return response

Multi-Tenant Example

Scenario: Company A and Company B both use Jira

Company A:

  • Tenant ID: company-a
  • Jira: https://company-a.atlassian.net

Company B:

  • Tenant ID: company-b
  • Jira: https://company-b.atlassian.net

What Happens:

  1. Company A's first request:

    • JWT contains tenant_id: "company-a" and Jira config
    • System checks cache: constellation:connection:company-a:jira:hash
    • Cache miss → Creates new JiraService → Caches it
    • Request proceeds with Company A's connection
  2. Company A's second request:

    • Same JWT, same config
    • Cache hit → Reuses cached connection
    • Faster response (no connection creation)
  3. Company B's request:

    • JWT contains tenant_id: "company-b" and Jira config
    • System checks cache: constellation:connection:company-b:jira:hash
    • Cache miss → Creates new JiraService for Company B
    • Completely separate from Company A's connection
  4. Result:

    • Company A and Company B have isolated connections
    • Each tenant's connections are cached separately
    • No cross-tenant access possible

Connection Caching

Cache Key Format

Connections are cached in Redis using this key format:

constellation:connection:{tenant_id}:{connection_type}:{config_hash}

Example Keys:

constellation:connection:company-a:jira:a1b2c3d4
constellation:connection:company-a:github:e5f6g7h8
constellation:connection:company-b:jira:i9j0k1l2

Connection Hash

The connection hash is generated from the connection configuration:

  • Same config = same hash = same cached connection
  • Different config = different hash = separate connection

This means:

  • If Company A changes their Jira credentials, a new connection is created
  • If Company A uses the same credentials, the connection is reused

Cache TTL

Connections are cached for 24 hours by default. After this time:

  • The connection expires from cache
  • Next request creates a new connection
  • New connection is cached again

Benefits

1. Performance

  • Connection Reuse: Avoids creating new connections for every request
  • Reduced Latency: Cached connections respond faster
  • Resource Efficiency: Fewer connection objects in memory

2. Security

  • Tenant Isolation: Complete separation between tenants
  • No Data Leakage: Impossible for Company A to access Company B's data
  • JWT-based: All tenant info comes from signed JWT tokens

3. Scalability

  • Horizontal Scaling: Stateless design allows multiple API instances
  • Redis Shared State: All instances share connection cache
  • TTL Expiration: Old connections automatically expire

Managing Connections

View Connection Statistics

Check how many connections are cached for your tenant:

curl http://localhost:3007/admin/connections/stats \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: your-jwt-token"

Response:

{
"success": true,
"data": {
"tenant_id": "company-a",
"total_connections": 2,
"connections_by_type": {
"jira": 1,
"github": 1
}
}
}

Clear Cached Connections

Clear all cached connections for your tenant (useful for testing):

curl -X DELETE http://localhost:3007/admin/connections \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: your-jwt-token"

Clear specific connection type:

curl -X DELETE "http://localhost:3007/admin/connections?connection_type=jira" \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: your-jwt-token"

Response:

{
"success": true,
"message": "Cleared connections for tenant company-a",
"connection_type": "all"
}

Testing Connection Management

Test Scenario: Verify Tenant Isolation

  1. Generate JWT for Company A:

    # Edit scripts/generate_jwt.py with Company A credentials
    python scripts/generate_jwt.py
    # Copy JWT_A
  2. Make request as Company A:

    curl http://localhost:3007/jira/projects \
    -H "X-API-KEY: your-api-key" \
    -H "X-JWT-Token: JWT_A"
  3. Check Company A's connections:

    curl http://localhost:3007/admin/connections/stats \
    -H "X-API-KEY: your-api-key" \
    -H "X-JWT-Token: JWT_A"
    # Should show 1 Jira connection for company-a
  4. Generate JWT for Company B and repeat:

    # Edit scripts/generate_jwt.py with Company B credentials
    python scripts/generate_jwt.py
    # Copy JWT_B
  5. Verify isolation:

    • Company A stats should only show company-a connections
    • Company B stats should only show company-b connections
    • Each tenant has separate, isolated connections

Test Connection Reuse

# Make multiple requests as Company A
for i in {1..5}; do
curl http://localhost:3007/jira/projects \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: JWT_A"
done

# Check stats - should still show 1 connection (reused)
curl http://localhost:3007/admin/connections/stats \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: JWT_A"

Best Practices

  1. Use Consistent Credentials: Same credentials = connection reuse = better performance
  2. Monitor Connection Stats: Regularly check connection statistics to understand usage
  3. Clear When Needed: Clear connections when credentials change or for testing
  4. Understand TTL: Connections expire after 24 hours automatically
  5. Test Isolation: Always verify tenant isolation in your tests

Troubleshooting

Connections Not Being Cached

Symptoms: Every request creates a new connection

Possible Causes:

  • Redis is not running
  • Redis connection error in logs
  • Connection config changing between requests

Solution:

# Check Redis is running
redis-cli ping

# Check Redis connection in .env
REDIS_HOST=localhost
REDIS_PORT=6379

# Check logs for Redis errors

Stats Showing Wrong Counts

Symptoms: Connection stats don't match expected counts

Solution:

# Clear all connections
curl -X DELETE http://localhost:3007/admin/connections \
-H "X-API-KEY: your-api-key" \
-H "X-JWT-Token: your-jwt-token"

# Make fresh requests
# Check stats again

Cross-Tenant Access Concerns

Symptoms: Worried about tenant isolation

Verification:

  • Check JWT tokens have correct tenant_id
  • Verify connection keys include tenant_id in Redis
  • Review logs for connection creation
  • Test with two different tenants