Skip to content

lsd-consulting/lsd-core

Repository files navigation

CI Nightly Build GitHub release Maven Central

LSD Core

Living Sequence Diagrams - Automatically generate interactive sequence diagrams from your code

LSD Core transforms how you document system interactions. Instead of manually maintaining sequence diagrams that quickly become stale, capture interactions programmatically and generate living documentation that stays in sync with your code.

Key Features:

  • Generate sequence diagrams without writing PlantUML markup
  • Interactive HTML reports with clickable event details
  • Component diagrams showing system-wide relationships
  • Automatic diagram splitting for complex flows
  • Multiple output formats and customizable themes

Use Cases:

  • Document API interactions in integration tests
  • Visualize microservice communication patterns
  • Debug complex distributed system flows
  • Generate architecture documentation from tests
  • Create onboarding materials automatically

LSD_example

Table of Contents

Why LSD?

Traditional Approach

@startuml
User -> API: POST /login
API -> Database: SELECT * FROM users
Database --> API: user data
API --> User: 200 OK
@enduml

Problems:

  • Manual maintenance required
  • Quickly becomes outdated
  • No connection to actual code
  • Limited interactivity

LSD Approach

// In your test or application code
lsd.capture(
    ("User" messages "API") { label("POST /login") },
    ("API" messages "Database") { label("SELECT * FROM users") },
    ("Database" respondsTo "API") { label("user data") },
    ("API" respondsTo "User") { label("200 OK") }
)

Benefits:

  • Generated from actual execution
  • Always in sync with code
  • Interactive HTML with details
  • Automatic from tests

Features at a Glance

Feature Description
Zero Markup No PlantUML syntax to learn - just Java/Kotlin code
Living Documentation Diagrams generated from actual execution, not manual drawings
Interactive Reports Click any interaction to see full request/response details
Multiple Diagrams Sequence diagrams + component diagrams from same data
Test Integration JUnit 5 and Cucumber plugins available
HTTP Interception Auto-capture REST/HTTP calls with interceptors
Customizable Themes, colors, participant types, custom icons
Large Diagram Support Auto-splitting for complex flows
Offline Mode Works without internet (inline CSS/JS)

Quick Start

Installation

Add the dependency to your project: Maven Central

Maven
<dependency>
    <groupId>io.github.lsd-consulting</groupId>
    <artifactId>lsd-core</artifactId>
    <version>X.X.X</version>
</dependency>
Gradle
implementation 'io.github.lsd-consulting:lsd-core:X.X.X'

Basic Usage

Capture interactions using the LsdContext singleton:

Kotlin Example

(Kotlin DSL as below or alternatively use the Java style builder or create Message() instances directly)

fun main() {
    val lsd = LsdContext.instance

    // Capture message exchanges
    lsd.capture(
        ("User Service" messages "Auth Service") { label("POST /authenticate") },
        ("Auth Service" respondsTo "User Service") {
            label("200 OK")
            data("<token>")
        }
    )

    // Complete the scenario and generate report
    lsd.completeScenario("User Authentication Flow")
    lsd.completeReport("Authentication API")
}
Java Example
public static void main(String[] args) {
    LsdContext lsd = LsdContext.getInstance();
    
    lsd.capture(
        messageBuilder()
            .from("User Service")
            .to("Auth Service")
            .label("POST /authenticate")
            .build(),
        messageBuilder()
            .from("Auth Service")
            .to("User Service")
            .label("200 OK")
            .data("<token>")
            .type(SYNCHRONOUS_RESPONSE)
            .build()
    );
    
    lsd.completeScenario("User Authentication Flow");
    lsd.completeReport("Authentication API");
}

Output: The generated HTML report will be in build/reports/lsd/ (configurable via properties).

Real-World Example

Here's how you might document an order processing flow:

@Test
fun `process order with payment`() {
    val lsd = LsdContext.instance
    
    // Customer places order
    lsd.capture(
        ("Customer" messages "Order Service") { label("POST /orders {items, total}") }
    )
    
    // Order service validates and requests payment
    lsd.capture(
        ("Order Service" messages "Payment Service") { label("POST /payments") },
        ("Payment Service" respondsTo "Order Service") { label("200 OK"); data("<transactionId>") }
    )
    
    // Order confirmed
    lsd.capture(
        ("Order Service" respondsTo "Customer") { 
            label("201 Created")
            data("<orderId>")
        }
    )
    
    lsd.completeScenario("Successful Order Processing")
    lsd.completeReport("E-Commerce API Flows")
}

This generates an interactive diagram showing the complete flow, with each arrow clickable to reveal request/response details.

Advanced Features

Customizing Participants

Enhance diagrams with typed participants that have custom colors and aliases:

// Define participants with visual styling
val frontend = BOUNDARY.called("Web App", "Frontend", "#3498db")
val api = CONTROL.called("API Gateway", "Gateway", "#2ecc71")
val userDb = DATABASE.called("PostgreSQL", "User DB", "#e74c3c")
val cache = DATABASE.called("Redis", "Cache", "#f39c12")
val queue = QUEUE.called("RabbitMQ", "Event Queue", "#9b59b6")

// Register participants for consistent styling across scenarios
lsd.addParticipants(listOf(frontend, api, userDb, cache, queue))

// Use in messages
lsd.capture(
    (frontend messages api) {
        label("GET /users/123")
        data("data for report diagram popup (may contain json, xml, html)")
    }
)

Available Participant Types:

Type Visual Best For
ACTOR Stick figure End users, external actors
BOUNDARY Box with side bar UI components, API boundaries
CONTROL Circle with arrow Controllers, orchestrators
DATABASE Cylinder Databases, data stores
ENTITY Circle Domain entities, models
QUEUE Queue icon Message queues, event streams
COLLECTIONS Stacked boxes Collections, lists
PARTICIPANT Simple box Generic components (default)

Sequence Events

Beyond messages, capture additional context with these event types:

// Add a title to the diagram
lsd.capture(PageTitle("User Registration Flow"))

// Add explanatory notes
lsd.capture(NoteOver("API", "Validates email format"))
lsd.capture(NoteLeft("Database", "Checks for existing user"))
lsd.capture(NoteRight("Email Service", "Sends welcome email"))

// Show async operations or delays
lsd.capture(TimeDelay("Processing..."))

// Split complex flows into multiple pages
lsd.capture(Newpage("Payment Processing"))

// Show active processing (useful for async operations)
lsd.capture(ActivateLifeline("Payment Processor", "#ff6b6b"))
// ... processing events ...
lsd.capture(DeactivateLifeline("Payment Processor"))

Available Event Types:

Event Use Case Example
PageTitle Set diagram title PageTitle("Authentication Flow")
NoteLeft Add context to the left NoteLeft("API", "Rate limited")
NoteRight Add context to the right NoteRight("DB", "Cached result")
NoteOver Add context over lifeline NoteOver("Service", "Retry logic")
TimeDelay Show elapsed time TimeDelay("5 seconds")
Newpage Split into pages Newpage("Error Handling")
ActivateLifeline Show active processing ActivateLifeline("Worker", "red")
DeactivateLifeline End active processing DeactivateLifeline("Worker")

Additional Capabilities

Generate an index page for multiple reports:

lsd.createIndex()

Create component diagrams showing relationships across all scenarios:

lsd.completeComponentsReport("Relationships")

Highlight important information with facts:

// The keyword "Lorem" will be highlighted throughout the report
lsd.addFact("Something to highlight", "Lorem")

Include custom icons (e.g., Font Awesome):

lsd.includeFiles(listOf("tupadr3/font-awesome-5/heart"))
lsd.capture(NoteLeft("Friends <$heart{scale=0.4,color=red}>"))

Configuration

Customize LSD behavior by adding an lsd.properties file to your classpath or setting system properties (which take precedence).

Property Default Description
lsd.core.label.maxWidth 200 Maximum label width (in characters) before abbreviation
lsd.core.diagram.theme plain PlantUML theme (available themes)
lsd.core.report.outputDir build/reports/lsd Output directory for report files
lsd.core.ids.deterministic false Generate deterministic HTML element IDs (useful for approval testing)
lsd.core.diagram.sequence.maxEventsPerDiagram 50 Maximum events per diagram before auto-splitting
lsd.core.devMode true Offline mode with inline CSS/JS (no CDN dependencies)
lsd.core.metrics.enabled false Experimental: Show performance metrics table

Gallery

Report Types

Sequence Diagrams with Metrics
LSD report example
Interactive Popups
Click arrows to view detailed event data
Popup example
Component Diagrams
Visualize all participants across scenarios
components report example
Index Pages
Navigate between multiple reports
index page example

Ecosystem

LSD Core is the foundation library. Several companion libraries automate diagram generation for popular testing frameworks:

FAQ

How does LSD differ from manually writing PlantUML?

LSD generates diagrams from actual code execution, ensuring they stay synchronized with your implementation. You can capture events during tests, and the diagrams are always accurate.

Can I use LSD with existing test frameworks?

Yes! Check out the Ecosystem section for integrations with JUnit, Cucumber, and HTTP interceptors that automatically capture interactions.

What's the performance impact?

LSD is designed for test and development environments. In production, you can disable event capture or use conditional logic. Event capture is lightweight, but diagram generation should happen offline.

Can I customize the diagram appearance?

Yes! You can use any PlantUML theme, customize participant colors, add notes, and control diagram layout. See Configuration and Advanced Features.

How do I handle large diagrams?

LSD automatically splits diagrams when they exceed lsd.core.diagram.sequence.maxEventsPerDiagram (default: 50 events). You can also manually split using Newpage events.

Development

Prerequisites

  • Java 17 JDK

Building

./gradlew clean build

Git hooks are configured automatically on first build (uses .githooks directory).

Troubleshooting

CDN Cache Issues

Static files (CSS/JS) are cached on JSDelivr CDN for up to 7 days. To force a cache refresh:

  1. Use the JSDelivr Purge tool
  2. Purge these files:
    • https://cdn.jsdelivr.net/gh/lsd-consulting/lsd-core@5/src/main/resources/static/style.min.css
    • https://cdn.jsdelivr.net/gh/lsd-consulting/lsd-core@5/src/main/resources/static/custom.min.js
  3. Clear your browser cache

Tip: Use lsd.core.devMode=true (default) to avoid CDN issues during development.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE.txt file for details.

About

Core components for generating reports with sequence diagrams

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •