Lesson 6 Complete Solution

This lesson demonstrates clean workflow and activity separation through a comprehensive user onboarding process with multiple coordinated activities.

What's Included

Workflow Architecture

  • workflow/UserOnboardingWorkflow.kt - Main workflow interface
  • workflow/UserOnboardingWorkflowImpl.kt - Orchestration logic with proper error handling

Activity Components

  • activity/UserValidationActivity.kt + UserValidationActivityImpl.kt - Email validation
  • activity/AccountCreationActivity.kt + AccountCreationActivityImpl.kt - Account creation
  • activity/NotificationActivity.kt + NotificationActivityImpl.kt - Welcome notifications

Key Learning Points

Clean Separation of Concerns

Each activity has a single, well-defined responsibility:

  • Validation: Input validation and business rules
  • Account Creation: Database operations and ID generation
  • Notification: External service integration

Proper Error Handling

  • Validation failures stop the process early
  • Account creation failures are critical errors
  • Notification failures are treated as non-critical (best effort)

Activity Configuration

Different activities have different timeout configurations based on their expected behavior:

// Quick validation - 10 seconds
val validationActivity = Workflow.newActivityStub(..., 10 seconds)

// Database operations - 30 seconds  
val accountCreationActivity = Workflow.newActivityStub(..., 30 seconds)

// External services - 1 minute
val notificationActivity = Workflow.newActivityStub(..., 1 minute)

Data Flow Architecture

UserOnboardingWorkflow
│
├── ValidationActivity
│   ├── Email format validation
│   ├── Duplicate email checking
│   └── Business rule validation
│
├── AccountCreationActivity  
│   ├── User ID generation
│   ├── Database record creation
│   └── Default settings initialization
│
└── NotificationActivity
    ├── Email composition
    ├── External service calls
    └── Delivery confirmation

Running This Code

1. Register Components

worker.registerWorkflowImplementationTypes(UserOnboardingWorkflowImpl::class.java)
worker.registerActivitiesImplementations(
    UserValidationActivityImpl(),
    AccountCreationActivityImpl(),
    NotificationActivityImpl()
)

2. Execute Workflow

val workflow = workflowClient.newWorkflowStub(
    UserOnboardingWorkflow::class.java,
    WorkflowOptions.newBuilder()
        .setTaskQueue("onboarding-queue")
        .setWorkflowId("onboard-${System.currentTimeMillis()}")
        .build()
)

val result = workflow.onboardUser("newuser@example.com")
println("Onboarding result: $result")

3. Expected Output

Starting user onboarding for: newuser@example.com
Step 1: Validating user data
Validating user: newuser@example.com
✅ User validation passed for: newuser@example.com
Step 2: Creating user account
Creating account for: newuser@example.com
✅ Account created successfully with ID: user_abc12345
Step 3: Sending welcome notification
📧 Welcome email sent successfully to: newuser@example.com
User onboarding completed successfully

Best Practices Demonstrated

✅ Single Responsibility Principle

Each activity does one thing well and can be tested independently.

✅ Proper Error Handling

  • Critical vs non-critical failures
  • Graceful degradation for notification failures
  • Detailed error messages and logging

✅ Activity Timeouts

Different timeout strategies based on expected operation duration.

✅ Data Modeling

Clear, typed data structures for communication between workflow and activities.

✅ Logging Strategy

  • Workflow logs track orchestration decisions
  • Activity logs show detailed operation progress
  • Emojis and clear formatting for easy debugging

Next Steps

Lesson 7 will explore workflow input/output patterns and more complex data handling scenarios!

results matching ""

    No results matching ""