SpringOne Platform 2016: Bootiful Microservices in a Legacy Environment: Lessons Learned

Speaker: David Julia
Twitter: DavidJulia

 

In a Microservices Architecture

Services are cheap and fast to deploy and change independently.

Spring Boot

Simple and cheap to spin up a new microservice!
Autoconfiguration

Legacy Environment

An environment wherein many systems that are hard to change are in dire need of replacement or augmentation to meet business demands.

The importance of DDD in Legacy Environments

Domain-Driven Design is key! Lean on it!
Don’t couple your domain model to your legacy system’s models

You need to evolve to Microservices

appcontinuum.io

Succession Patterns

  • Strangler Application Pattern
  • Characterization tests – a vice

What’s the plan?

  • Identify behavior we need
  • “Sprout” a new class to hold behavior we want
  • Start moving behavior into that class
  • Sprout a component (JAR)

Premature Extraction

  • Extracting a Service too early can be costly
  • It’s easier to refactor the system with an in-process component
  • Only have to change things in one place

What did we just see

  • Started with a ball of mud
  • Identified/Extracted behavior into new classes
  • Packaged classes as JAR
  • Created a new service (strangler application)
  • Did all of this safely and with high confidence

Links

Simon Brown on Modular Monoliths
Working Effectively with Legacy Code

SpringOne Platform 2016: Testing with Spring 4.3, JUnit 5, and Beyond

Speaker: Sam Brannen
Twitter: @sam_brannen

Agenda

  • Spring Events App
  • Spring 4.3
  • JUnit 5
  • Spring 5

Spring Events App

The Spring Events App is a Spring boot powered web app using
Spring Boot 1.4, Spring Framework 5, JUnit 5.

Odds & Ends

  • JUnit 4.12+ required by the Spring TestContext framework (TCF)
  • Support for Primary transaction managers and data sources in TCF
  • @Sql and @Sqlgroup many now be used as meta-annotations:
    • to create custom composed annotations with attribute overrides
    • Same is true for many @Repeatable annotations in Core Spring
  • ReflectionTestUtils automatically unwraps proxies when setting/getting a field

Extending the Spring TextContext Framework

  • The getTestContext() method in TestContextManager is now public
  • New ContextCustomizer and ContextCustomizerFactory SPIs
    • Potentially replaces need for custom ContextLoader
    • Customize ApplicationContext after bean definitions are loaded but before context is refreshed
    • Registered globally by third parties via spring.factories mechanism
    • Enables Spring Boot Test Magic

New Features

  • SpringRunner alias for the SpringJUnit4ClassRunner
    >> @RunWith(SpringRunner.class)
  • @ContextConfiguration can be completely omitted…
    • if default XML or @Configuration is detected
    • Spring Boot test 1.4 even locates your @SpringBootApplication class
  • ApplicationContext cache is now bounded

Preparing for the Future

  • Testing Traits
    • Spring test annotations can be declared on interfaces
    • Combines nicely with Java 8 default methods and JUnit 5
  • Non-public @Transactional test methods: for use with JUnit 5 and TestNG
  • Non-public @BeforeTransaction and @AfterTransaction methods

MockMvc Improvements

  • Expectations on multi-value response headers: HeaderResultMatchers.stringValues(…)
  • Form data equest content (e.g., from a POST) now parsed and used to populate request params
  • Support for Custom HTTP verbs (e.g. WebDAV)
  • Improve Cookie support for HtmlUnit integration

MockMvc – Assert invoked Handler Method

New mock-like methodCall() assertion in HandlerResultMatchers: Assert the @Controller method invoked to handle the response:

    mockMvc.perform(get("/"))
    .andExpect(handler().methodCall(
     on(HomeController.class).showHomePage()));

MockMvc – JSON Prefixes

New support for stripping JSON prefixes from Responses. A prefix is used to prohibit JSON hijacking:

    mockMvc.perform(get("/account/42").accept(APPLICATION_JSON))
    .andExpect(jsonPath("$.pin")
    .prefix("&&enigma&&")
    ...

MockRestServiceServer Improvements

  • Expectations for form data in the request body
  • Specify expectation counts
    • Pass ExpectedCount to the expect() method
    • once(), manyTimes(), times(int), min(int), max(int), between(int, int)
    • verify() and reset() afterwards
  • Specify whether ordering should be ignored: invoke ignoreExpectOrder(true) on the MockResetServiceServerBuilder

JUnit 5: Impetus for Change

  • JUnit 4.0 was released a decade ago
  • Modularity -> big ball of mud (i.e., only THE junit.jar)
  • Test Discovery and execution -> tightly coupled
  • Extensibility -> lot of room for improvement
  • Java 8 support

JUnit 4 Runner API

  • Very Powerful
  • You can do anything
  • But you cannot combine Runners
  • Parameterized + SpringJUnit4ClassRunner -> no way

JUnit 4… Rules… are meant to be broken

  • JUnit 4.7: MethodRule -> @Rule
  • JUnit 4.9: TestRule -> @Rule/@ClassRule

JUnit Lambda

  • Initiated by Johannes Link and Marc Philipp
  • Later joined by Matthias Merdes, Stefan Bechtold, and Sam Brannen

JUnit 5 – Roadmap

  • Prototype – December 2015
  • Alpha – February 2016
  • M1 & M2 – July 2016
  • M3, M4, RC1 – Fall 2016
  • GA – End of 2016… maybe

JUnit 5 – In a Nutshell

  • Modular
  • Extensible
  • Modern
  • Forward & Backward Compatible
    • JUnit Platform supports JUnit 3.8, 4 and 5
    • New testing frameworks can be run with JUnit 4 infrastructure:
      @RunWith(JUnitPlatform.class)

JUnit 5 = Platform + Jupiter + Vintage

  • JUnit Platform 1.0.0
    • Foundation for launching testing frameworks on the JVM
    • Launcher and TestEngine APIs
    • ConsoleLauncher, Gradle Plugin, Maven Surefire provider
  • JUnit Jupiter 5.0.0: New programming model and extension model for JUnit 5
  • JUnit Vintage 4.12.0: TestEngine for running old stuff

Launcher API

  • Used by IDEs and build tools to launch the framework
  • Central API for discovering and executing tests via one or more engines
  • LauncherDiscoveryRequest: Selectors and filters
  • Feedback provided via the TestExecutionListener API

TestEngine API

  • aka, Runner in JUnit 4
  • Test engine discovers and executes tests for a particular programming model
  • Automatic registration via Java’s ServiceLoader mechanism
  • JupiterTestEngine
  • VintageTestEngine
  • Implement your own…

Extension APIs

  • BeforeAllCallback
  • BeforeEachCallback
  • BeforeTestExecutionCallback
  • AfterTestExecutionCallback
  • AfterEachCallback
  • AfterAllCallback
  • ContainerExecutionCondition & TestExecutionCondition
  • TestInstancePostProcessor
  • ParameterResolver
  • TestExecutionExceptionHandler

JUnit 5 – Programming Model

org.junit.jupiter.api

  • Annotations & Meta-annotations
  • Assertions & Assumptions
  • Custom Display Names
  • Visibility
  • Tagging
  • Conditional Test Execution
  • DI for Constructors and methods
  • Lambda Expressions and method references
  • Interface default methods
  • Nested test classes
  • Dynamic Tests

Annotations

  • @Test / @TestFactory
  • @BeforeAll / @AfterAll
  • @BeforeEach / @AfterEach
  • @DisplayName
  • @Tag
  • @Disabled
  • @Nested

Assertions

org.junit.jupiter.api.Assertions

  • Limited set of core assertions
  • assertThrows() and expectThrows()
  • assertTimeout()
  • assertAll()

SpringOne Platform 2016: Intro to Spring Boot

Speaker: Eddú Meléndez
Twitter: @EdduMelendez

 

Spring Ecosystem: The Spring Framework

  • Spring Social
  • Spring Web Services
  • Spring Integration
  • Spring AMQP
  • Spring Hatecas
  • Spring Mobile
  • Spring Security
  • Spring Data
  • Spring Batch

Spring Boot is not ingredients but the whole cake

XML Config > Java Config > Spring Boot Configuration

spring.datasource.username=sa
spring.datasource.password=password

Why Spring Boot?

    • Convention over Configuration
    • Provide dependency Management
    • Auto-configuration
    • Starter Dependencies
    • Actuator

Demo

start.spring.io

or via the command line:

curl https://start.spring.io

or using Spring CLI:

spring run appname

Properties

Defining properties in Spring:

@ConfigurationProperties(prefix="conference")
public class ConferenceProperties {
    ...
}

In application.properties:

conference.name=Spring One Platform
conference.location=Aria Hotel, Las Vegas

Spring Actuator

Provides various health and configuration metrics about your Spring application.

        • /health
        • /metrics
        • /env

Spring Boot Starter Security

Default username is ‘user’ and password is generated

Of course, can be configured:

@Configuration
public class SecurityConfig extends GlobalAuthenticationConfigurerAdapter {
    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication...
    }
}

SpringOne Platform 2016: Testing Spring Boot Applications

Speaker: Phil Webb, @phillip_webb
Project: github.com/philwebb/testing-spring-boot-applications

Spring requires no-arg constructors, but there’s no reason that these have to be public: make them protected if it makes sense.

You need tests for:

  1. Domain Layer
  2. Service Layer
  3. Web Layer

@RunWith(SpringRunner.class)

Service Layer Testing

@JSonTest to test JSON format
@MockBean to mock a dependency

Web Layer testing

Test class annotation:
@WebMvcTest


@Autowired
private MockMvc mvc

@MockBean

@AutoConfigureMockMvc
@AutoConfigureTestDatabase

SpringOne Platform 2016: Wall St. Derivative Risk Solutions Using Apache Geode

Speaker: Andre Langevin, CIBC
Speaker: Mike Stolz, Pivotal
White Paper: http://pivotal.io/building-wall-street-risk-applications
Geode: http://geode.incubator.apache.org

GemFire is the commercial offering of Geode

Design

  • Input: Trades
  • Input: Market Data
  • Output: Risk
  • Where the Magic Happens: Risk Calculations
  • Geode is the backbone infrastructure

A Crash Course in Wall Street

  • Big Wall Street firms have “FICC” trading business organized by market
    • Each business will trade “cash” and derivative products, but traders specialize in one or the other
    • There may be a team of traders working to trade a single product
  • Trading systems are product specific and often highly specialized
  • Managing these businesses requires a consolidated view of risk

Calculating Risk

  • What is the “risk” that we are trying to measure?
  • Markets are represented using curves
  • Consistency is paramount

Technology Solutions that Work Badly

  • The easiest thing to do is just book all your trades using one trading system
  • How about booking all of the hedges into the primary trading system?
  • How about adding up all of the risk from each trading system into a report

Designing and Naming Data Objects

  • The trade data model serves 2 distinct purposes
  • Market data should follow the calculation design
  • Use “dot” notation to give business-friendly keys to object (i.e., USD.LIBOR.3M)

Region Design

  • Trade and market data regions
  • Typically a curve embeds a list for rates — leave it denormalized if rates are updated slowly
  • Computational results and aggregation
  • Regions: Rates, Trades, Curves, Built Curves, FX, Trade Risk, Risks, Agg

Placing Regions on the Cluster

  • Region placement optimizes the solution’s performance
  • Partition the trades regions to balance the cluster
  • Partition or replicate market data to optimize computations

PDX Integration Glue

  • PDX serialization is an effective cross-language bridge
  • Structure PDX objects to optimize performance
  • JSON is a good message format

Getting Trade Data into Geode

  • Message formats vary by product type
  • Broker messages in an application server
  • Trade data capture is transactional: Best practive is to make end-to-end process a transaction, but may need to split into two legs based on source of messages

Getting Market Data into Geode

  • Market data feeds have many proprietary formats
  • Market data is often exceptionally fast moving
  • Market data can also be very slow moving: i.e., LIBOR
  • Conflate fast market data by sampling
  • Gate market data into batches

Crunching Numbers on a Shared Grid

  • Most trading firms have a proprietary math library
  • Pushing Geode events to an external compute grid: Asynchronous Event Queue (AEQ)
  • Caching locally on the grid to accelerate performance: Wildcards on keys

Crunching Numbers Inside Geode

  • Running the math inside Geode is dramatically faster
  • Using the Geode grid as a compute grid
  • Using cache listeners to propagate valuation events

Ticking Risk Views

  • Roll-your-own client applications to view ticking risk
  • Integrating packaged products: ION Enterprise Risk, Armanta Theatre, Active Pivot…
  • The Traders always want spreadsheets: Write an Excel plug-in

SpringOne Platform 2016: Building Applications with Angular JS and Spring Security

Speaker: Dave Syer, @david_syer

Agenda

  • Real quick intro to Spring Security, Spring Session, Angular JS
  • Focus on features to build secure, modern, single-page applications
  • High level view of sample apps presented in tutorial (from blog series)
  • More Details look at some features of the apps

Most valuable links

Spring Security

  • Generic Filter based solution for Servlet applications
  • Authentication (a.k.a. identity) and Authorization (a.k.a. access decisions)
  • OAuth2 module useful for SSO and token-based API authentication
  • lots of other features
  • http://projects.spring.io/spring-security

Angular JS

  • Javascript Framework
  • “Magic” binding (dependency injection and MVC)
  • Has a lot of traction in the enterprise
  • Nothing about the architecture of the apps presented here requires Angular JS
  • Really basic usage in sample, but representative

Security Features in Modern Browsers

  • HTTP Basic
  • X.509 authentication
  • Kerberos
  • Kerberos
  • Cookies
  • CORS (Common Origin Resource Sharing)
  • HSTS (HTTP Strict Transport Security
  • CSP (Content Security Policy)

Sub-text: “use them, they’re reliable and free…”

Spring Session

  • Not tied to Spring Security, but works well with it
  • Easy, declarative, distributed sessions
  • Redis works out of the box, other backends easy to add
  • Servlet Filter
  • http://cloud.spring.io

Add HTTP Basic Security

  • Add spring-boot-starter-security dependency
  • Set security.user.password=password to application.properties
  • Add SecurityConfiguration extends WebSecurityConfigurerAdapter
  • Suppress the Browser Dialog by adding X-Requested-With XmlHttpRequest in HTTP request

Cross Site Request Forgery (CSRF)

  • Spring Security and Angular JS both have good support for CSRF protection
  • HTTP Request Header: X-CSRF-TOKEN

CORS

  • Use @CrossOrigin on your @RequestMapping and this: http.cors()
  • Tip: there is also CorsUtils::isCorsRequest method you can use in a request matcher