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: 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

Spring MVC and JSTL MessageSource Configuration

I’ve been working on a new web application over the last month whenever I can find some spare time.   I had initially started the project using Grails, but I had difficulty getting past the scaffolding.   Besides, my reading seems to always come back to Grails performance issues so I figured I’d just start with a tried & true Java Enterprise stack:  Spring, Hibernate, Spring MVC, and MySQL.

I spent the last few weeks dealing with the model, DAO, service, and controller layers.   I’m aiming for a solid RESTful API consuming and producing JSON from the onset.  I got all that to work seemingly well and am now actually ready to focus on views so I wrote my first JSP in about 10 years yesterday:

    <%@ include file="taglibs.jsp"%>
    <head>
        <title><fmt:message key="home.title"/></title>
    </head>
    <body class="home">
        <fmt:message key="home.heading"/>
    </body>

Now in my maven /src/main/resources directory, I have a message.properties file containing the following:

    home.properties=Home
    home.heading=Hello World!

Finally, I added the following to my MVC Configuration file (I’m using JavaConfig as opposed to the old school Spring XML):

    @Bean
    public MessageSource getMessageSource() {
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        source.setBasename("messages");
        return source;
    }

Not really any rocket science here, folks… This is pretty much standard based on the Spring documentation and about half a dozen blog entries.   The only difference with my configuration and what I found online was that the MessageSource was being configured using XML.

I spent several hours trying to get this to work but the view would render with ???home.title??? and ???home.heading??? and I couldn’t for the life of me figure out what the problem was.   I know that the bean was getting instantiated because I added a breakpoint there…   Finally I tried actually retrieving the MessageSource bean in the controller from the ApplicationContext.   Instead, I got a big fat exception that the bean was not found.    So I changed my configuration to retrieve the bean by name instead of by class:

    @Bean(name="messageSource")
    public MessageSource getMessageSource() {
         ResourceBundleMessageSource source = new ResourceBundleMessageSource():
         source.setBasename("messages"):
         return source;
     }

Just like magic, the JSP view now rendered just fine! Simply naming the bean ‘messageSource’ resolved a problem I had been tackling for several hours. I realize this blog doesn’t have an insane amount of traffic, but hopefully this will help somebody who runs into the same problem I did.