seedstack feature tour

49
SeedStack tour Adrien LAUER

Upload: seedstack

Post on 18-Feb-2017

285 views

Category:

Software


2 download

TRANSCRIPT

SeedStack tour

Adrien LAUER

Outline

Overview of the full stackJava frameworkBusiness frameworkWeb frameworkFrontend/backend integrationTooling

OVERVIEW OF THE FULL STACK

What is SeedStack?A full-stack development solution– Java backend–Web frontend

A scalable architecture for enterprise software

An extensible ecosystem of add-ons

General architecture

Java framework Web framework

Add-on1

Business framework

Add-on4

Add-on2

Add-on3

Add-on 5

Add-on6

Add-on7

REST APIs

Application backend

REST APIs

Application frontend

ModularityModularity at every level of the stack– Clear separation of APIs from impl.– One module per concern– Powerful extension mechanisms (plugins,

fragments, API/SPI)

Automatic integration of modules– Auto-discovery– Every module just works without effort

DistributionGlobal packaging of all modules

Archetypes for quick project creation

Each organization can roll its own custom distribution

16.4 16.7 16.11

Add-onsPersistence: JDBC, JPA, MongoDB, Redis, Neo4J, Solr, ElasticSearch

Communication: JMS, Web-Services, JavaMail, MQTT

Bridges: W20 bridge, Spring bridge

Features: dynamic i18n, batch monitoring, import/export, audit, validation, cache, scheduling

UI themes: simple, business, material

JAVA FRAMEWORK

Core

Java framework modules

Kernel

Lifecycle LoggingConfiguration Diagnostic

Commands Bindings

Web CLI Testing

Transactions Security REST

Metrics

Services

Kernel + plugin architecture

A concern per plugin

Each plugin is responsible for:1. Submitting classpath scan requests to the kernel2. Providing initialization, startup and shutdown code3. Building a Guice module

The kernel orchestrates all plugins:– Resolve dependencies between plugins– Invoke init, startup and shutdown code

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); }}

Dependency injection

Each plugin provides a Guice module– Define injection bindings– Is dynamically created by the plugin

All modules are aggregated and used to produce a global injector

Only javax.inject API is used in application code

Modular configuration

Configuration files go in META-INF/configuration– They are scanned upon startup– They are merged into one unique configuration

Configuration values can be accessed from anywhere in the application

Feature-rich: profiles, macros, environment variables, system properties, override, converters, …

Sample configuration[org.seedstack]jdbc.datasources = main-datasourcejpa.units = my-unit

[org.seedstack.seed]core.application-id = my-appcore.application-name = My applicationserver.port<heroku> = ${env:PORT}

[org.seedstack.jdbc.datasource.main-datasource]driver = org.hsqldb.jdbcDriverurl = jdbc:hsqldb:mem:store

[org.seedstack.jpa.unit.my-unit]datasource = main-datasourceproperty.hibernate.dialect = org.hibernate.dialect.HSQLDialectproperty.hibernate.hbm2ddl.auto = update

[org.seedstack.samples.myapp.domain.*]jpa-unit = my-unit

Exceptions and diagnosticReadable, content-rich technical exceptions:

– Templatable message and fix advice– Concise list of causes– Online reference if relevant

When an unexpected exception occurs:– Extensive diagnostic info is collected– A JSON diagnostic report is dumped to the filesystem if possible

Custom diagnostic collectors and reporters can be plugged in

Great support tool

Sample exception traceorg.seedstack.seed.SeedException: (CORE) Unexpected exception

Causes------1. java.lang.RuntimeException: (JPA) No persisted classes in unit2. (JPA) No classes were found belonging to JPA unit "my-unit".

Fix---Verify that the classes are correctly scanned and they are configured to belong to the JPA unit "my-unit".

Online information------------------http://seedstack.org/addons/jpa#configuration

Stacktrace----------...

Security

Based on Apache Shiro

Modular permission-based security model

Built-in and pluggable security realms:– Static configuration– LDAP– X509 certificate

Fine-grained data obfuscation

REST

JAX-RS 2.0 through Jersey 2

Hypermedia capable:– JSON-HOME for discovering entry resources– Registry of rels– Builder of HAL representations and links

Swagger generator via add-on

More…Fully injectable Servlet and Filters

WebSockets

Command-line parsing

Transactions

Metrics collection and reporting

Applicative SSH shell

Benefits

Lays ground for software componentization at the enterprise scale:– Provides and promotes modularity– Enables quick integration of components without

effort

Solves common technical challenges once for the whole organization

BUSINESS FRAMEWORK

Building blocks

Levels of abstraction

Annotations

Interfaces

Base classes

Low framework couplingLow dev speed

High framework couplingHigh dev speed

Entitiespublic class Customer extends BaseEntity<String> {

private String email; private Address address;

public Customer (String email) { this.email = email;

}

@Override public String getEntityId() {

return this.email; }

// … more}

Value Objectspublic class Address extends BaseValueObject {

private final String street; private final String city; private final ZipCode zipCode;

public Address(String street, String city, ZipCode zipCode) {

this.street = street; this.city = city; this.zipCode = zipCode;

}

// … more}

Aggregatespublic class Order extends BaseAggregateRoot<OrderId> {

private OrderId orderId; private Date checkoutDate; private double totalPrice;

public Order(OrderId orderId) { this.orderId = orderId; }

@Override public OrderId getEntityId() { return this.orderId ; }

// … more}

ServicesDefine an interface:

@Service public interface CheckoutService { public Invoice checkout(Order order); }

And one or more implementation(s):@Named(“creditCard")public class CreditCardCheckoutService implements CheckoutService { @Override public Invoice checkout(Order order) { ... } }

Qualifies implementation if there are multiple ones

RepositoriesBasic repositories without effort:

@Inject @Jpa private Repository<Customer, String> customerRepository;

Can be extended with custom methods:

public interface CustomerRepository extends GenericRepository<Customer, String> { List<Customer> findByName(String firstName, String lastName); }

@Jpapublic class CustomerJpaRepository extends BaseJpaRepository<Customer, String> implements CustomerRepository { @Override public List<Customer> findByName (String firstName, String lastName) { ... } }

Also available with other technologies

Qualifies implementation if there are multiple ones

FactoriesConstructor-based factories without effort:

@Injectprivate Factory<Customer> customerFactory;

Can be extended with custom methods:

public interface CustomerFactory extends GenericFactory<Customer> { Customer createCustomer(String email, String firstName, String lastName);}

public class CustomerFactoryImpl extends BaseFactory<Customer> implements CustomerFactory { @Override public Customer createCustomer(String email, String firstName, String lastName) { ... } }

Can be plugged in with identity generators (provided or custom)

More…

Domain policies

Domain events

DTO/Aggregate assembling

Finders and pagination

Benefits

Proven approach to produce quality and maintainable software

Promotes software industry best-practices

Homogenize business code accross projects

Design for reuse

WEB FRAMEWORK

Loader + fragment architecture

Allows composability of Web frontends

Each fragment contains:– A manifest describing its contents– Static assets like modules, stylesheets, templates, …

The W20 loader aggregates all fragments and orchestrate the initialization of the Single-Page Application

Loading sequence

Sample fragment{ "id": "my-fragment", "name": "My awesome fragment",

"modules": { "module1": "{my-fragment}/modules/module1" },

"...": { … },

"...": { … }}

Identity

1. Modules are loaded by the W20 loader first2. Then each loaded module can process

fragment sections to further initialize the application

Paths can be relative to the fragment manifest

Additional abitrary section

Sample configuration{ "/path/to/my-fragment.w20.json": { "modules": { "module1": { … } }, "vars": { "var1": "value1" } }}

Fragment manifest URL

Module configuration object

Define values of fragment manifest’s variables

Features

AngularJS integrationCulture and internationalizationIntegration with backend securityNavigation and menu managementHypermediaPluggable CSS frameworksTheming

Simple theme

Material theme

Business theme

Benefits

Provides a component architecture for Web frontends

Provides useful services for Web enterprise applications (security, i18n, navigation …)

Provides theming support

Solves common technical challenges once for the whole organization

FRONTEND/BACKEND BRIDGE

Features

Seamless Java/Web integration:– Auto-detects W20 fragments in classpath– Implements REST API required by frontend– Dynamically generates the W20 configuration and the

masterpage

Can be extended through an SPI

Enables activation of a front/back feature simply by adding a dependency

TOOLING

SeedStack tools

Maven plugin:– Generate: generate projects from scratch– Run: run a project from command-line– Package: creates a runnable unique JAR

Yeoman generator for pure-frontend modules

Grunt plugin for bundling and minification

PROJECT

Open-SourceBusiness-friendly license: MPL 2.0

100% open-source:– Core frameworks– 25+ official add-ons– Tools– Documentation (CC BY-SA)

Can be extended with proprietary add-ons without restriction

Communityhttp://seedstack.org

https://github.com/seedstack

@seedstack

http://stackoverflow.com/questions/tagged/seedstack

#seedstack on freenode