Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
176 lines (142 sloc) 10.6 KB
title permalink
Context Map Discovery
/docs/reverse-engineering/

Our "context map discovery" or "reverse engineering" library allows to derive a CML context map from existing source code. If you work in a project with an existing monolith you may want to generate a CML Bounded Context with your domain model. Afterwards, you can analyze and decompose the architecture with our tools. This simplifies the start with our tool and avoids huge efforts to re-model the existing system. If your system already has a (micro-)service-oriented architecture you may want to reverse engineer the CML context map illustrating all bounded contexts and their relationships.

The discovery library supports to reverse engineer bounded contexts and context maps (relationships between bounded contexts). It is extensible and designed to plug-in new discovery strategies. The current prototype supports bounded context discovery for Spring Boot applications and relationship discovery on the basis of Docker compose.

Contributions to the discovery library are very welcome! If you implement a new discovery strategy for another programming language or framework, please contribute it to our project and create a PR in our Github repository.

Usage

The latest version of the discovery library is available through Maven Central: Maven Central

You can find all information about the library, how to use it and how to extend it with new discovery strategies, in our Github repository:

https://github.com/ContextMapper/context-map-discovery

Note that this is a prototype and limited in the discovery strategies already implemented. New strategies have to be implemented in the future.

Lakeside Mutual Case Study

The following example illustrates how the discovery library works. We applied it to the Lakeside Mutual project, a fictitious insurance company. It is a sample application to demonstrate microservices. With our context map discovery library we derived a CML context map from the Lakeside Mutual source code.

The following diagram provided by the project itself illustrates the architecture:

Lakeside Mutual Architecture Overview

With the strategies already available we are able to discover the bounded contexts:

  • Customer Management
  • Customer Self-Service
  • Policy Management
  • Customer Core

The risk management context is currently not detected, since a strategy on the basis of Node.js is not available yet.

The following piece of code is all which is needed to generate the context map with our library:

public class LakesideMutualContextMapDiscoverer {

  public static void main(String[] args) throws IOException {
    // configure the discoverer
    ContextMapDiscoverer discoverer = new ContextMapDiscoverer()
        .usingBoundedContextDiscoveryStrategies(
            new SpringBootBoundedContextDiscoveryStrategy("com.lakesidemutual"))
        .usingRelationshipDiscoveryStrategies(
            new DockerComposeRelationshipDiscoveryStrategy(
                new File(System.getProperty("user.home") + "/source/LakesideMutual/")))
        .usingBoundedContextNameMappingStrategies(
            new SeparatorToCamelCaseBoundedContextNameMappingStrategy("-") {
              @Override
              public String mapBoundedContextName(String s) {
                // remove the "Backend" part of the Docker service names to map correctly...
                String name = super.mapBoundedContextName(s);
                return name.endsWith("Backend") ? name.substring(0, name.length() - 7) : name;
              }
            });

    // run the discovery process to get the Context Map
    ContextMap contextmap = discoverer.discoverContextMap();

    // serialize the Context Map to CML
    new ContextMapSerializer().serializeContextMap(contextmap, new File("./src-gen/lakesidemutual.cml"));
  }

}

The library is based on strategies implementing the three interfaces BoundedContextDiscoveryStrategy, RelationshipDiscoveryStrategy, and BoundedContextNameMappingStrategy. The BoundedContextNameMappingStrategy strategy can be used to map different bounded context names between the bounded context and relationship strategies.

In this example we use the SpringBootBoundedContextDiscoveryStrategy to discover the bounded contexts on the basis of Spring annotations. It derives bounded contexts from applications, aggregates from REST endpoints, and Entities from the REST endpoint methods. The DockerComposeRelationshipDiscoveryStrategy strategy is used to derive the relationships between the bounded context from the docker-compose.yml file. The extended SeparatorToCamelCaseBoundedContextNameMappingStrategy in the example above is used to map names such as 'customer-management-backend' (name according to relationship strategy) to 'CustomerManagement' (name according the discovered bounded context).

The code above creates the following context map for the application:

ContextMap {
  contains PolicyManagement
  contains CustomerManagement
  contains CustomerSelfService
  contains CustomerCore

CustomerCore -> PolicyManagement

CustomerCore -> CustomerManagement

PolicyManagement -> CustomerSelfService

CustomerCore -> CustomerSelfService

}

BoundedContext PolicyManagement { implementationTechnology "Spring Boot" // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.policymanagement.interfaces.RiskComputationService. Aggregate riskfactor // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.policymanagement.interfaces.InsuranceQuoteRequestInformationHolder. Aggregate PolicyManagement_insurance_quote_requests { /* removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.policymanagement.interfaces.PolicyInformationHolder. Aggregate policies { / removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.policymanagement.interfaces.CustomerInformationHolder. Aggregate PolicyManagement_customers { / removed to save space here */ } }

BoundedContext CustomerManagement { implementationTechnology "Spring Boot" // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customermanagement.interfaces.CustomerInformationHolder. Aggregate CustomerManagement_customers { /* removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customermanagement.interfaces.InteractionLogInformationHolder. Aggregate interaction_logs { / removed to save space here */ } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customermanagement.interfaces.NotificationInformationHolder. Aggregate notifications }

BoundedContext CustomerSelfService { implementationTechnology "Spring Boot" // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customerselfservice.interfaces.AuthenticationController. Aggregate auth // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customerselfservice.interfaces.CityStaticDataHolder. Aggregate cities { /* removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customerselfservice.interfaces.InsuranceQuoteRequestInformationHolder. Aggregate insurance_quote_requests { / removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customerselfservice.interfaces.CustomerInformationHolder. Aggregate customers { / removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customerselfservice.interfaces.UserInformationHolder. Aggregate user { / removed to save space here */ } }

BoundedContext CustomerCore { implementationTechnology "Spring Boot" // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customercore.interfaces.CityStaticDataHolder. Aggregate CustomerCore_cities { /* removed to save space here / } // This Aggregate has been created on the basis of the Spring REST controller com.lakesidemutual.customercore.interfaces.CustomerInformationHolder. Aggregate CustomerCore_customers { / removed to save space here */ } }

We removed the entities in the CML model above in order to save space here. The full example and the projects source code can be found here.

You can’t perform that action at this time.