実例で学ぶ、明日から使えるSpring Boot Tips #jsug

Post on 12-Apr-2017

5.110 views 3 download

Transcript of 実例で学ぶ、明日から使えるSpring Boot Tips #jsug

‹#›© 2016 Pivotal Software, Inc. All rights reserved. ‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot Tips

Toshiaki Maki (@making) tmaki@pivotal.io Spring 2017 Feb 2017-02-27

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Who am I ?• Toshiaki Maki (@making) https://ik.am

•Sr. Solutions Architect @Pivotal

•Spring ☘ / Cloud Foundry ☁ / Concourse ✈ / BOSH 🐚

bit.ly/hajiboot2

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot is ....•Opinionated Framework on Spring Ecosystem

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot is ....•Opinionated Framework on Spring Ecosystem

Spring Boot Way

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

https://goo.gl/Ey1y3X

https://github.com/openenquete/enquete

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.jar

Thymeleaf

Spr

ing

Dat

a JP

A

Spring Data REST

Spring MVC

MySQL

Spr

ing

Sec

urity

O

Aut

h

Cloud Foundry

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.jar

Thymeleaf

Spr

ing

Dat

a JP

A

Spring Data REST

Spring MVC

MySQL

Spr

ing

Sec

urity

O

Aut

h

Cloud Foundry

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.jar

Thymeleaf

Spr

ing

Dat

a JP

A

Spring Data REST

Spring MVC

MySQL

Spr

ing

Sec

urity

O

Aut

h

Cloud Foundry

AJAX / REST

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.jar

Thymeleaf

Spr

ing

Dat

a JP

A

Spring Data REST

Spring MVC

MySQL

Spr

ing

Sec

urity

O

Aut

h

Cloud Foundry

AJAX / REST

GitHub

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.jar

Thymeleaf

Spr

ing

Dat

a JP

A

Spring Data REST

Spring MVC

MySQL

Spr

ing

Sec

urity

O

Aut

h

Cloud Foundry

AJAX / REST

GitHub

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Errororg.springframework.boot.autoconfigure.web.DefaultErrorViewResolver

src/main/resources /static/error/403.html 404.html 40x.html 500.html 50x.html

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Errororg.springframework.boot.autoconfigure.web.DefaultErrorViewResolver

src/main/resources /templates/error/403.<ext> 404.<ext> 40x.<ext> 500.<ext> 50x.<ext>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="${@environment.acceptsProfiles('default')}"> <tr> <th>Status</th><td th:text="${status}"></td> </tr> <tr> <th>Error</th><td th:text="${error}"></td> </tr> <tr> <th>Exception</th><td th:text="${exception}"></td> </tr> <tr> <th>Message</th><td th:text="${message}"></td> </tr> </table>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="${@environment.acceptsProfiles('default')}"> <tr> <th>Status</th><td th:text="${status}"></td> </tr> <tr> <th>Error</th><td th:text="${error}"></td> </tr> <tr> <th>Exception</th><td th:text="${exception}"></td> </tr> <tr> <th>Message</th><td th:text="${message}"></td> </tr> </table>

profile default

disabled

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="${@environment.acceptsProfiles('default')}"> <tr> <th>Status</th><td th:text="${status}"></td> </tr> <tr> <th>Error</th><td th:text="${error}"></td> </tr> <tr> <th>Exception</th><td th:text="${exception}"></td> </tr> <tr> <th>Message</th><td th:text="${message}"></td> </tr> </table>

profile default

disabled

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="..."> <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="..."> <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>

server.error.include-stacktrace=alwaysapplication-default.properties

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

<table th:if="..."> <!-- --> <tr th:if="${trace}"> <th>Trace</th> <td><pre th:text="${trace}"></pre></td> </tr>

server.error.include-stacktrace=alwaysapplication-default.properties

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@ControllerAdvice(annotations = Controller.class) public class ErrorControllerAdvice { @ExceptionHandler(NoSuchElementException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String noSuchEelemtException() { return "error/404"; } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@ControllerAdvice(annotations = Controller.class) public class ErrorControllerAdvice { @ExceptionHandler(NoSuchElementException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String noSuchEelemtException() { return "error/404"; } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@Autowired Environment env; @ExceptionHandler(NoSuchElementException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public String ex(NoSuchElementException e, Model model) { addErrors(e, HttpStatus.NOT_FOUND, model); return "error/404"; }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

void addErrors(Exception e, HttpStatus status, Model model) { if (env.acceptsProfiles("default")) { StringWriter stackTrace = new StringWriter(); e.printStackTrace(new PrintWriter(stackTrace)); stackTrace.flush(); model.addAttribute("status", status.value()); model.addAttribute("error", status.getReasonPhrase()); model.addAttribute("exception", e.getClass()); model.addAttribute("message", e.getMessage()); model.addAttribute("trace", stackTrace.toString()); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

void addErrors(Exception e, HttpStatus status, Model model) { if (env.acceptsProfiles("default")) { StringWriter stackTrace = new StringWriter(); e.printStackTrace(new PrintWriter(stackTrace)); stackTrace.flush(); model.addAttribute("status", status.value()); model.addAttribute("error", status.getReasonPhrase()); model.addAttribute("exception", e.getClass()); model.addAttribute("message", e.getMessage()); model.addAttribute("trace", stackTrace.toString()); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Profile

• java -jar app.jar --spring.profiles.active=prod• java -jar -Dspring.profiles.active=prod app.jar• export SPRING_PRPFILES_ACTIVE=prod

Cloud Foundry

cloud

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Data REST REST API

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public interface FooRepository extends CrudRepository<Foo, Long> {}

Repository --> REST API

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public interface FooRepository extends CrudRepository<Foo, Long> {}

Repository --> REST API

GET /foosPOST /foosGET /foos/{fooId}PUT /foos/{fooId}DELETE /foos/{fooId}PATCH /foos/{fooId}...

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> {}

GET /foos?page={page} &size={size}&sort={sort}...

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { List<Foo> findByName(String name); }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends PagingAndSortingRepository<Foo, Long> { List<Foo> findByName(String name); }

GET /foos/search/findByName?name={name}...

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends Repository<Foo, Long> { @RestResource(exported = false) List<Foo> findBySeminarId(Long seminarId); Optional<Foo> findOne(Long id); void save(Foo foo); }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Repository --> REST API

public interface FooRepository extends Repository<Foo, Long> { @RestResource(exported = false) List<Foo> findBySeminarId(Long seminarId); Optional<Foo> findOne(Long id); void save(Foo foo); } GET /foos/{id}

POST /foos

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RepositoryEventHandlerTraditional

Spring Data REST

Controller Service Repository

Repository EventHandler

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RepositoryEventHandler@RepositoryEventHandler @Componentpublic class UsernameEventHandler { @HandleReforeCreate void setUsername(UsernameHolder holder) { String username = SecurityContextHolder .getContext().getAuthentication() .getName(); holder.setUsername(username); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

RepositoryEventHandler@RepositoryEventHandler @Componentpublic class UsernameEventHandler { @HandleReforeCreate void setUsername(UsernameHolder holder) { String username = SecurityContextHolder .getContext().getAuthentication() .getName(); holder.setUsername(username); } }

UserHolderusername

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Bean Validation@Configuration public class RestConfig extends RepositoryRestConfigurerAdapter { private final Validator vldtr; /* constructor */ @Override public void configureValidatingRepositoryEventListener(...) { lstnr.addValidator("beforeCreate", vldtr); lstnr.addValidator("beforeSave", vldtr); }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Bean Validation@Configuration public class RestConfig extends RepositoryRestConfigurerAdapter { private final Validator vldtr; /* constructor */ @Override public void configureValidatingRepositoryEventListener(...) { lstnr.addValidator("beforeCreate", vldtr); lstnr.addValidator("beforeSave", vldtr); }}

{ "errors": [{ "entity": "ResponseForSession", "property": "difficulty", "invalidValue": null, "message": "may not be null" }, { "entity": "ResponseForSession", "property": "satisfaction", "invalidValue": null, "message": "may not be null" } ]}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Traditional

Spring Data REST

Controller Service Repository

Repository EventHandler

@Transactional

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Traditional

Spring Data REST

Controller Service Repository

Repository EventHandler

@Transactional

RepositoryEntity Controller

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Traditional

Spring Data REST

Controller Service Repository

Repository EventHandler

@Transactional

RepositoryEntity Controller

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Traditional

Spring Data REST

Controller Service Repository

Repository EventHandler

@Transactional

RepositoryEntity Controller

AOP

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

• https://blog.ik.am/entries/403

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

CSRF•Spring Security CSRF

•Ajax / SPA

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

CSRF•Spring Security CSRF

•Ajax / SPApublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable()/* ... */; }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

CSRF•Spring Security CSRF

•Ajax / SPApublic class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable()/* ... */; }}

🙅

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

$.post('/user', { firstName: 'Fred', lastName: 'Flintstone', _csrf: $('input[name=_csrf]').val() });

$(document).ajaxSend(function(e, xhr, options) { var token = $('input[name=_csrf]').val(); xhr.setRequestHeader('X-CSRF-TOKEN', token);});

OR

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

I don't like jQuery😟

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http./* ... * /and().csrf() .csrfTokenRepository( CookieCsrfTokenRepository .withHttpOnlyFalse()); } }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

HTTP (_csrf) HTTP

(X-CSRF-TOKEN) CSRF HTTP

( )

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

HTTP (_csrf) HTTP

(X-CSRF-TOKEN) CSRF HTTP

( )

HTTP (_csrf) HTTP

(X-XSRF-TOKEN) CSRF

Cookie(name=XSRF-TOKEN, httpOnly)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Axios• https://github.com/mzabriskie/axios

• node.js Promise HTTP

• XSRF-TOKEN Cookie HTTP

X-XSRF-TOKEN (AngularJS )

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Axios• https://github.com/mzabriskie/axios

• node.js Promise HTTP

• XSRF-TOKEN Cookie HTTP

X-XSRF-TOKEN (AngularJS )

axios.post('/response_for_seminar', { comment: 'Great!', request: 'Sushi!' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

OAuth2 SSO with GitHub

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-oauth2</artifactId> </dependency>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

code

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

codecode

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

codecode

token

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

codecode

token

token

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Authorization Code (grant_type=authorization_code)

Authorization Server (GitHub)

Web UI

Resource Server (GitHub API)

authorize

redirect

codecode

token

token

response

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@EnableOAuth2Sso@SpringBootApplication@EnableOAuth2Sso public class EnqueteApplication { public static void main(String[] args) { SpringApplication.run(EnqueteApplication.class, args); }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

security.oauth2.client.client-id=xxxxxsecurity.oauth2.client.client-secret=xxxxxsecurity.oauth2.client.access-token-uri=https://github.com/login/oauth/access_tokensecurity.oauth2.client.user-authorization-uri=https://github.com/login/oauth/authorize security.oauth2.resource.user-info-uri=https://api.github.com/user

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

PrincipalExtractor / AuthoritiesExtractor

public interface PrincipalExtractor { Object extractPrincipal(Map<String, Object> map);}

public interface AuthoritiesExtractor { List<GrantedAuthority> extractAuthorities(Map<String, Object> map);}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public EnqUserPrincipalExtractor implements AuthoritiesExtractor { @Override Object extractPrincipal(Map<String, Object> map){ return new EnqUser(map.get("name"), map.get("email"), map.get("avatar_url")); }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public EnqUserPrincipalExtractor implements AuthoritiesExtractor { @Override Object extractPrincipal(Map<String, Object> map){ return new EnqUser(map.get("name"), map.get("email"), map.get("avatar_url")); }}

security.oauth2.resource.user-info-uri

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public EnqUserAuthoritiesExtractor implements PrincipalExtractor { @Override List<GrantedAuthority> extractAuthorities(Map<String, Object> map){ return Arrays.asList( !"making".equals(map.get("login")) ? new SimpleGrantAuthority("ROLE_USER") : new SimpleGrantAuthority("ROLE_ADMIN") ) }

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

code

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

codecode

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

codecode

token

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

codecode

token

token

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

codecode

token

token

response

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

GitHub OK

Authorization Server

Web UI

Resource Server

authorize

redirect

codecode

token

token

response

@EnableAuthorizationServer

@EnableResourceServer

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

UI SSO

Authorization Server

Web UI

Resource ServerAnother Web UI

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

• https://github.com/Pivotal-Japan/spring-security-oauth-workshop

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

public interface UrlShortenerClient { String shorten(String longUrl);}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@ConditionalOnProperty

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@Component@ConditionalOnProperty(name = "enquete.bitly.access-token")public BitlyClient implements UrlShortenerClient { @Override String shorten(String longUrl) { String token = props.getBitly() .getAccessToken(); /* ... */ }}

Bit.ly URL

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@Component@ConditionalOnProperty(name = "enquete.googl.api-key")public GooglClient implements UrlShortenerClient { @Override String shorten(String longUrl) { String apiKey = props.getGoogl().getApiKey(); /* ... */ }}

Goo.gl URL

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.bitly.access-token=0123456789

enquete.googl.api-key=abcdef

BitlyClient

GooglClient

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@Controllerpublic SeminarController { final Optional<UrlShortenerClient> shortener; @GetMapping("seminars/{seminarId}") public String list(...) { shortener.ifPresent(x -> { String shorten = x.shorten(url); model.addAttribute("shorten", shorten); }); /* ... */ }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.bitly.access-token=0123456789

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.bitly.access-token=0123456789

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

enquete.bitly.access-token=0123456789enquete.googl.api-key=abcdef

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

@ConfigurationProperties@ConfigurationProperties(prefix = "enquete")@Component @Validatedpublic class EnqProps { private Set<String> adminUsers; private Bitly bitly; public static class Bitly {

private String accessToken; } // setter/getter}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Configuration Processor

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</scope>

</dependency>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot Actuator >= 1.5• (ROLE_ACTUATOR)

• /info, /health (status )

management.security.enabled=falseapplication-default.properties

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Boot Actuator >= 1.5• (ROLE_ACTUATOR)

• /info, /health (status )

management.security.enabled=falseapplication-default.properties

profile default

disabled

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

ROLE_ACTUATORpublic EnqUserAuthoritiesExtractor /* ... */ { @Override List<GrantedAuthority> extractAuthorities(Map<String, Object> map){ return !"making".equals(map.get("login")) ? asList(new SimpleGrantAuthority("ROLE_USER")) : asList(new SimpleGrantAuthority("ROLE_ADMIN"), new SimpleGrantAuthority("ROLE_ACTUATOR")) }}

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

BeansViz<dependency> <groupId>am.ik.beansviz</groupId> <artifactId>beansviz-spring-boot-actuator</artifactId> <version>0.1.0</version></dependency>

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

BeansViz<dependency> <groupId>am.ik.beansviz</groupId> <artifactId>beansviz-spring-boot-actuator</artifactId> <version>0.1.0</version></dependency>

Actuator /beansviz

/beans Graphviz

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

• https://blog.ik.am/entries/401

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Error Spring Data REST

CSRF @EnableOAuth2Sso

@ConditionalOnProperty

Configuration Properties

Spring Boot Actuator

Cloud Foundry Integration

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Check Source code!

https://github.com/openenquete/enquete

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Spring Cloud Services in PWS• https://content.pivotal.io/blog/building-spring-microservices-

with-cloud-foundrys-new-container-networking-stack

‹#›© 2016 Pivotal Software, Inc. All rights reserved.

Check Tutorials!!•https://github.com/Pivotal-Japan •https://pivotal-japan.connpass.com/