> ## Documentation Index
> Fetch the complete documentation index at: https://platform.docs.zenoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Local Development Guide

> Guide for local Hub development using LocalStack and in-memory storage

# Local Development Guide

Guide for developing and testing the Zenoo Hub locally without requiring AWS cloud services.

## Overview: Two Approaches

The Hub supports two approaches for local development:

1. **Local Provider** (Recommended) - In-memory storage with zero dependencies
2. **LocalStack** - AWS service emulation for testing AWS-specific behavior

### Quick Comparison

| Aspect           | Local Provider     | LocalStack               |
| ---------------- | ------------------ | ------------------------ |
| **Setup**        | 1 config line      | Docker + configuration   |
| **Startup**      | `<100ms`           | \~10 seconds             |
| **Dependencies** | None               | Docker, LocalStack image |
| **Memory**       | Low (\~50MB)       | High (\~500MB)           |
| **Persistence**  | None (volatile)    | Optional (volumes)       |
| **AWS Accuracy** | N/A                | \~90%                    |
| **Use Case**     | Quick dev, testing | AWS behavior testing     |

### When to Use Local Provider

**Use local provider when:**

* Developing features that don't depend on AWS-specific behavior
* Running unit and integration tests
* Building CI/CD pipelines
* Quick prototyping and experimentation
* No need for data persistence
* Want instant startup and teardown

**Configuration:**

```yaml theme={null}
hub:
  cloud:
    provider:
      type: local  # That's it!
```

[Complete local provider guide](/technical-specification/hub-backend/cloud-providers/local)

### When to Use LocalStack

**Use LocalStack when:**

* Testing AWS-specific features (DynamoDB queries, TTL, etc.)
* Validating AWS configuration before deployment
* Testing multi-region behavior
* Need persistence between restarts
* Developing AWS-specific integrations

**Configuration:**

```yaml theme={null}
hub:
  cloud:
    provider:
      type: aws
  aws:
    region: us-east-1
    dynamodb:
      endpoint: http://localhost:4566
```

## Local Provider Setup

The local provider requires minimal setup and is perfect for most local development scenarios.

### 1. Add Dependency

Already included in `backend-integration-tests` and `sample-hub-instance`:

```gradle theme={null}
dependencies {
    implementation project(':backend-spring-boot-starter')
    implementation project(':cloud-provider-local')
}
```

### 2. Configure

**application-local.yml:**

```yaml theme={null}
hub:
  cloud:
    provider:
      type: local

  local:
    cleanupEnabled: true
    cleanupInterval: 5m
    verboseLogging: false

# Other Hub configuration...
kafka:
  bootstrap-servers: localhost:9092
```

### 3. Run

```bash theme={null}
./gradlew bootRun --args='--spring.profiles.active=local'
```

The Hub will start instantly with in-memory storage. All data is lost on restart.

### Testing with Local Provider

**Example Integration Test:**

```groovy theme={null}
@SpringBootTest
@TestPropertySource(properties = [
    "hub.cloud.provider.type=local"
])
class ComponentStorageTest {

    @Autowired
    LocalComponentStore componentStore

    @BeforeEach
    void setUp() {
        // Clear storage between tests
        componentStore.clear()
    }

    @Test
    void "should store and retrieve component"() {
        given:
        ComponentId id = ComponentId.of("test-workflow", "1.0")
        StringComponent component = StringComponent.builder()
            .id(id)
            .definition("workflow { }")
            .build()

        when:
        componentStore.store(component).block()

        then:
        StringComponent retrieved = componentStore.get(id).block()
        retrieved.id == id
        retrieved.definition == "workflow { }"
    }
}
```

### CI/CD with Local Provider

Perfect for continuous integration:

```yaml theme={null}
# .github/workflows/integration-test.yml
name: Integration Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'corretto'

      - name: Run Integration Tests
        run: ./gradlew integrationTest
        env:
          HUB_CLOUD_PROVIDER_TYPE: local  # No AWS credentials needed!
```

## LocalStack Setup

LocalStack provides local emulation of AWS services.

### Installation

#### Using Docker

```bash theme={null}
docker run -d \
  --name localstack \
  -p 4566:4566 \
  -e SERVICES=dynamodb,secretsmanager \
  localstack/localstack
```

#### Using Docker Compose

```yaml theme={null}
# docker-compose.yml
version: '3.8'

services:
  localstack:
    image: localstack/localstack
    ports:
      - "4566:4566"
    environment:
      - SERVICES=dynamodb,secretsmanager
      - DEBUG=1
      - DATA_DIR=/tmp/localstack/data
    volumes:
      - ./localstack-data:/tmp/localstack/data
```

Start with:

```bash theme={null}
docker-compose up -d
```

### Hub Configuration for LocalStack

```yaml theme={null}
# application-local.yml
hub:
  cloud:
    provider:
      type: aws

  aws:
    region: us-east-1
    accessKey: test
    secretKey: test
    dynamodb:
      endpoint: http://localhost:4566
      prefix: local-hub
      createTables: true
    secrets:
      endpoint: http://localhost:4566
      prefix: local-hub
```

### Running the Hub

```bash theme={null}
# Run with local profile
./gradlew bootRun --args='--spring.profiles.active=local'
```

### Accessing LocalStack Services

#### DynamoDB

```bash theme={null}
# List tables
aws dynamodb list-tables \
  --endpoint-url http://localhost:4566

# Scan components table
aws dynamodb scan \
  --table-name local-hub-components \
  --endpoint-url http://localhost:4566
```

#### Secrets Manager

```bash theme={null}
# List secrets
aws secretsmanager list-secrets \
  --endpoint-url http://localhost:4566

# Get secret value
aws secretsmanager get-secret-value \
  --secret-id local-hub/component-config/test/1.0 \
  --endpoint-url http://localhost:4566
```

## Testing

### Unit Tests

Run unit tests without any cloud services:

```bash theme={null}
./gradlew test
```

### Integration Tests with LocalStack

```bash theme={null}
# Start LocalStack
docker-compose up -d localstack

# Run integration tests
./gradlew integrationTest

# Stop LocalStack
docker-compose down
```

### Test Configuration

```yaml theme={null}
# application-test.yml
hub:
  aws:
    region: us-east-1
    accessKey: test
    secretKey: test
    dynamodb:
      endpoint: http://localhost:4566
      prefix: test-hub
      createTables: true
    secrets:
      endpoint: http://localhost:4566
      prefix: test-hub
```

## IntelliJ IDEA Setup

### Run Configuration

1. Create new Spring Boot run configuration
2. Set main class: `com.zenoo.hub.HubApplication`
3. Set active profiles: `local`
4. Set environment variables:
   ```
   SPRING_PROFILES_ACTIVE=local
   AWS_REGION=us-east-1
   ```

### Debug Configuration

Same as run configuration with debug mode enabled.

## Troubleshooting

### LocalStack Not Starting

```bash theme={null}
# Check logs
docker logs localstack

# Restart LocalStack
docker restart localstack
```

### Tables Not Created

```bash theme={null}
# Manually create tables
aws dynamodb create-table \
  --table-name local-hub-components \
  --attribute-definitions \
    AttributeName=componentName,AttributeType=S \
    AttributeName=revision,AttributeType=N \
  --key-schema \
    AttributeName=componentName,KeyType=HASH \
    AttributeName=revision,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST \
  --endpoint-url http://localhost:4566
```

### Connection Refused

Check LocalStack is running:

```bash theme={null}
curl http://localhost:4566/_localstack/health
```

## See Also

* [AWS Provider Guide](/technical-specification/hub-backend/cloud-providers/aws)
* [Testing Documentation](/technical-specification/hub-backend/testing)
* [Configuration Reference](/technical-specification/hub-backend/cloud-providers/configuration-reference)
