seedstack, the lean development stack

Post on 12-Apr-2017

390 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

The lean development stackAdrien LAUER

SeedStack

2 of 24

HistoryProject started late 2012

10+ years experience of frameworksCustomOpen-Source: mainly Spring

3 of 24

GoalsBuild a common development stack

Shared across all business entitiesManufacturing / logistics / finance / sales / R&D / …

Being extensible

Enabling re-use

4 of 24

OrganizationCore team at PSA Peugeot CitroënOther members at various locations

http://seedstack.orghttps://github.com/seedstackTwitter: @seedstackIRC: #seedstack on freenode

5 of 24

Get presentation code samples at

https://github.com/adrienlauer/poss-samples

6 of 24

Core valuesOpinion

A reference architecture for your apps

ModularitySingle responsibility principle

ExtensibilityOpen-Closed principle

7 of 24

FoundationJavaSet of technologies to build backends

WebSet of technologies to build Web apps

BusinessDomain-Driven Design (DDD) approach

8 of 24

FoundationJavaSet of technologies to build backends

WebSet of technologies to build Web apps

BusinessDomain-Driven Design (DDD) approach

9 of 24

Java focusKernel + plugin architecture

One plugin per concernScalable

One global Guice injector

Unified configuration

Plugin discovery

Classpath scan Initialization

10 of 24

Sample pluginpublic class MyPlugin extends AbstractPlugin { private final Set<Class<?>> annotatedClasses = new HashSet<>();

@Override public String name() { return "my-plugin"; }

@Override public Collection<ClasspathScanRequest> classpathScanRequests() { return classpathScanRequestBuilder().annotationType(Service.class).build(); }

@Override public InitState init(InitContext initContext) { annotatedClasses.addAll(initContext.scannedClassesByAnnotationClass().get(Service.class)); return InitState.INITIALIZED; }

@Override public Object nativeUnitModule() { return (Module) binder -> annotatedClasses.forEach(binder::bind); }}

11 of 24

So we built the core…Contains the kernel

Provides basic featuresLaunchingConfigurationIoCService commandsDiagnostics

12 of 24

Then we scaled up…10+ plugins

TestingSecurityTransactionsRESTMetrics / healthWeb…

Adding new technologies is quick and easy

All PSA requirements have been covered

50 satisfied projects over two years

13 of 24

FoundationJavaSet of technologies to build REST backends

WebSet of technologies to build Web apps

BusinessDomain-Driven Design (DDD) approach

14 of 24

Web focusLoader + fragments architecture

A fragment per concernComposable

Configure and initialize an SPA

Fragment download

Configuration computing Initialization

15 of 24

Sample fragment{ "id": "demo", "name": "W20 POSS demo", "modules": { "user": "{demo}/modules/user" }, "i18n": { "en": [ "{demo}/i18n/messages-en.json" ], "fr": [ "{demo}/i18n/messages-fr.json" ] }, "routes": { "hello": { "template": "<div class=\"container\"><h1>Hello World!</h1></div>", "hidden": true }, "user": { "templateUrl": "{demo}/views/user.html", "controller": "UserController" } }}

16 of 24

Main featuresBased on popular libraries

AngularJSRequireJS

Advanced enterprise features

Multi CSS frameworkBootstrapAngular material

Theming support2 Open-Source themes3 PSA proprietary themes

17 of 24

FoundationJavaSet of technologies to build REST backends

WebSet of technologies to build Web apps

BusinessDomain-Driven Design (DDD) approach

18 of 24

Level of involvement

Annotations

Interfaces

Base classes

19 of 24

Building blocks

20 of 24

Main featuresDDD semantic + injection

Easy-to-use default implementations

Smart DTO / domain mapping

Built-in identity generation strategies

21 of 24

Sampleclass SaleServiceImpl implements SaleService { private final Repository<Seller, Long> sellerRepository; private final DomainRegistry domainRegistry;

@Inject public SaleServiceImpl(Repository<Seller, Long> sellerRepository, DomainRegistry domainRegistry) { this.sellerRepository = sellerRepository; this.domainRegistry = domainRegistry; }

@Override public void updateBonus(Order order, Long sellerId) { Seller seller = sellerRepository.load(sellerId); if (seller == null) { throw new IllegalArgumentException("Seller " + sellerId + " cannot be found"); }

BonusPolicy bonusPolicy = domainRegistry .getPolicy(BonusPolicy.class, seller.getBonusPolicy());

double orderBonus = bonusPolicy.computeBonus(order); seller.addToMonthlyBonus(orderBonus);

sellerRepository.save(seller); }}

22 of 24

Extensibility20+ official add-ons

Audit, ElasticSearch, I18n, IO, JavaMail, JCache, JDBC, JMS, JPA, LDAP, MongoDB, Monitoring, Neo4J, Redis, Scheduling, Solr, Spring-bridge, Validation, W20-bridge, Web-Services, …

Open to third-partyhttp://seedstack.org/addons

PSA uses only 3 proprietary add-ons

23 of 24

DistributionGlobal packaging of all modules

Each organization can roll its own distribution

Open-Source reference distribution released 3 times per year

16.4 16.7 16.11

24 of 24

Thank you!Website: http://seedstack.orgGitHub: https://github.com/seedstackIRC: #seedstack on freenode

Contributions welcome!Pull requestsDocumentation fixesIssues

top related