69
Das kannste schon so machen… André Goliath

Das kannste schon so machen

Embed Size (px)

Citation preview

Page 1: Das kannste schon so machen

Das kannste schon so machen…

André Goliath

Page 2: Das kannste schon so machen

Disclaimer:This talk is bad

Because I had no timeBecause of the issues this talk is about

Page 3: Das kannste schon so machen

(makes sense, right?)

Page 4: Das kannste schon so machen

That being said…

Page 5: Das kannste schon so machen
Page 6: Das kannste schon so machen

Spring Boot & Netflix OSS StackWebServiceTemplate & Proxies

Jenkins & NPM

Page 7: Das kannste schon so machen

Spring Boot & Netflix OSS StackWebServiceTemplate & Proxies

Jenkins & NPM

Page 8: Das kannste schon so machen

You all know I´m a nice, calm, relaxed, chilled, error-forgiving

guy, right?

Page 9: Das kannste schon so machen
Page 10: Das kannste schon so machen

@ControllerAdvicepublic class GlobalControllerExceptionHandler extends ResponseEntityExceptionHandler { …

@ExceptionHandler({Exception.class}) private ResponseEntity<Object> handleAllUnknownExceptions(Exception ex) { return handleExceptionInternal(ex, null, null, HttpStatus.INTERNAL_SERVER_ERROR, null); }

@Override @ResponseBody protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {

BaseResponse errorMessage = createErrorMessage(ex); HttpStatus returnStatus = status != null ? status : HttpStatus.INTERNAL_SERVER_ERROR;

ResponseStatus exResponseStatus = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);

if (exResponseStatus != null) { returnStatus = exResponseStatus.value(); } return new ResponseEntity<>(errorMessage, headers, returnStatus); }

}

Page 11: Das kannste schon so machen

@Configuration@EnableWebMvcpublic class DispatcherServletConfigurer{

@Bean public FSLDispatcherServletHandlerErrorConfigurator getDispatcherServletPostProcessor(){ return new FSLDispatcherServletHandlerErrorConfigurator(); }

public class FSLDispatcherServletHandlerErrorConfigurator implements BeanPostProcessor {

public Object postProcessBeforeInitialization(Object bean, String beanName) throws …{ if (bean instanceof DispatcherServlet) { DispatcherServlet disp = ((DispatcherServlet) bean); disp.setThrowExceptionIfNoHandlerFound(true); } return bean; }… }

Page 12: Das kannste schon so machen

That´s so Spring Boot 1.2.x!(1.2 was released in Dec 2014, 1.3 in Nov 2015)

Page 13: Das kannste schon so machen

spring.mvc.throw-exception-if-no-handler-found=true spring.resources.add-mappings=false

(you still need the @ControllerAdvice though)

Page 14: Das kannste schon so machen

NETFLIX OSS

Page 15: Das kannste schon so machen

ConfigserverSpring Cloud ConfigService Registry eurekaReverse Proxy zuulCircuit Breaker hystrix

Page 16: Das kannste schon so machen

Client

Reverse Proxy(ZUUL)

Service Registry(EUREKA) Config Server

Page 17: Das kannste schon so machen

So how do you deliver the configuration

for all your microservices and environments?

Page 18: Das kannste schon so machen

HINT: NOT IN ONE BIG ZIP FILE

Page 19: Das kannste schon so machen

C:\YOURSTUFF\CONFIG-BAD\\+---development| global.yml| service-a.yml| service-b.yml| service-c.yml| | +---production| global.yml| service-a.yml| service-b.yml| service-c.yml| \---uat global.yml service-a.yml service-b.yml service-c.yml

Page 20: Das kannste schon so machen

C:\YOURSTUFF\CONFIG-BAD\\+---development| global.yml| service-a.yml| service-b.yml| service-c.yml| | +---production| global.yml| service-a.yml| service-b.yml| service-c.yml| \---uat global.yml service-a.yml service-b.yml service-c.yml

C:\YOURSTUFF\CONFIG-GOOD\\|-- development.yml|-- production.yml|-- uat.yml| +---service-a| service-a-development.yml| service-a-production.yml| service-a-uat.yml| +---service-b| service-b-development.yml| service-b-production.yml| service-b-uat.yml| \---service-c service-c-development.yml service-c-production.yml service-c-uat.yml

Page 21: Das kannste schon so machen

C:\YOURSTUFF\CONFIG-BAD\\+---development| global.yml| service-a.yml| service-b.yml| service-c.yml| | +---production| global.yml| service-a.yml| service-b.yml| service-c.yml| \---uat global.yml service-a.yml service-b.yml service-c.yml

C:\YOURSTUFF\CONFIG-GOOD\\|-- development.yml|-- production.yml|-- uat.yml| +---service-a| service-a-development.yml| service-a-production.yml| service-a-uat.yml| +---service-b| service-b-development.yml| service-b-production.yml| service-b-uat.yml| \---service-c service-c-development.yml service-c-production.yml service-c-uat.yml

Never usedashes In

service names!

Page 22: Das kannste schon so machen

What is that zuul anyway?And what does it do?

AND HOW DO WE USE IT?

Page 23: Das kannste schon so machen

@SpringBootApplication@Controller@EnableZuulProxypublic class ZuulApplication {

public static void main(String[] args) { new SpringApplicationBuilder(ZuulApplication.class) .web(true).run(args); }}

Page 24: Das kannste schon so machen

ZUUL DOES MUCH MORE THINGS THEN WE SEE!

Page 25: Das kannste schon so machen
Page 26: Das kannste schon so machen

NOTE TO SELF:SPRING DOES NOT USE SEMANTIC

VERSIONING!

Page 27: Das kannste schon so machen
Page 28: Das kannste schon so machen
Page 29: Das kannste schon so machen

Lessons learnedfrom working with Spring

Page 30: Das kannste schon so machen

NEVER TRUST DEFAULT VALUES

Page 31: Das kannste schon so machen

READ THE FRIENDLY MANUAL…

Page 32: Das kannste schon so machen

… AND ESPECIALLYTHE RELEASE NOTES!

Page 33: Das kannste schon so machen

Spring Boot & Netflix OSS StackWebServiceTemplate & Proxies

Jenkins & NPM

Page 34: Das kannste schon so machen

private WebServiceTemplate attachProxy(WebServiceTemplate template) { if (config.getUseProxy()) { template.setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort())) } return template; }}

Page 35: Das kannste schon so machen

private WebServiceTemplate attachProxy(WebServiceTemplate template) { if (config.getUseProxy()) { if (senderForProxy == null) { HttpClient client = HttpClients.custom() .setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort())) .build(); senderForProxy = new HttpComponentsMessageSender(client); } template.setMessageSender(senderForProxy); } return template; }}

Page 36: Das kannste schon so machen

org.springframework.ws.client.WebServiceIOException: I/O error: null; nested exception is org.apache.http.client.ClientProtocolException

at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:543)

...Caused by: org.apache.http.client.ClientProtocolException

at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:909)

... 32 moreCaused by: org.apache.http.ProtocolException: Content-Length header already present

... 39 more

Page 37: Das kannste schon so machen
Page 38: Das kannste schon so machen

private WebServiceTemplate attachProxy(WebServiceTemplate template) { if (config.getUseProxy()) { if (senderForProxy == null) { HttpClient client = HttpClients.custom() .setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort())) .addInterceptorFirst( new HttpComponentsMessageSender .RemoveSoapHeadersInterceptor() ) .build(); senderForProxy = new HttpComponentsMessageSender(client); } template.setMessageSender(senderForProxy); } return template; }}

Page 39: Das kannste schon so machen

SSL Protocol Error: Handshake failure

Page 40: Das kannste schon so machen
Page 41: Das kannste schon so machen

private WebServiceTemplate attachProxy(WebServiceTemplate template) { if (config.getUseProxy()) { if (senderForProxy == null) { HttpClient client = HttpClients.custom() .useSystemProperties() .setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort())) .addInterceptorFirst( new HttpComponentsMessageSender .RemoveSoapHeadersInterceptor() ) .build(); senderForProxy = new HttpComponentsMessageSender(client); } template.setMessageSender(senderForProxy); } return template; }}

Page 42: Das kannste schon so machen
Page 43: Das kannste schon so machen

400(a.k.a. „Bad Request“)

Page 44: Das kannste schon so machen

400(a.k.a. least helpful HTTP

response code of all times.)

Page 45: Das kannste schon so machen

…5 Hours of HTTP traffic comparison later…

SOAP-Namespaces?

Am I missing any HTTP header?Malformed XML?

No Proxy allowed? Still SSL issues?

Page 46: Das kannste schon so machen

…5 Hours of HTTP traffic comparison later…

Am I missing any HTTP header?

Page 47: Das kannste schon so machen
Page 48: Das kannste schon so machen

I am sending one header too much.

Am I missing any HTTP header?

Page 49: Das kannste schon so machen

private WebServiceTemplate attachProxy(WebServiceTemplate template) { if (config.getUseProxy()) { if (senderForProxy == null) { HttpClient client = HttpClients.custom() .useSystemProperties() .setProxy(new HttpHost(config.getProxyHost(), config.getProxyPort())) .addInterceptorFirst( new HttpComponentsMessageSender .RemoveSoapHeadersInterceptor() ) .build(); senderForProxy = new HttpComponentsMessageSender(client); senderForProxy.setAcceptGzipEncoding(false); } template.setMessageSender(senderForProxy); } return template; }}

Page 50: Das kannste schon so machen

It took me about 5 full days to get this right.

Page 51: Das kannste schon so machen

Lessons learnedfrom the proxy disaster

Page 52: Das kannste schon so machen

Have the samecommunication infrastructure

on every(!) test setup

Page 53: Das kannste schon so machen

No Proxy? Make your own.var http = require('http'), httpProxy = require('http-proxy');

var proxy = httpProxy.createProxyServer({});

var interceptingServer = http.createServer(function (req, res) { // define your custom logic to handle the request // and then proxy the request. proxy.web(req, res, {target: 'http://MyActualTargetService.com'});});

console.log("proxy listening on port 5050")interceptingServer.listen(5050);

https://github.com/nodejitsu/node-http-proxy

Page 54: Das kannste schon so machen

Talking about JavaScript…

Page 55: Das kannste schon so machen

Spring Boot & Netflix OSS StackWebServiceTemplate & Proxies

Jenkins & NPM

Page 56: Das kannste schon so machen
Page 57: Das kannste schon so machen

Node Package Manager v2is bad. Like, really bad.

Page 58: Das kannste schon so machen
Page 59: Das kannste schon so machen
Page 60: Das kannste schon so machen
Page 61: Das kannste schon so machen

So what’s the big deal?

Page 62: Das kannste schon so machen

npm install

…on Senacor Hardware: 15 min…on Clients Dev. Machine: 20 min…on Jenkins:. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Page 63: Das kannste schon so machen

Filesystem Size Used Avail Use% Mounted on.../dev/mapper/datavg-lv_optsoftware 492G 22G 446G 5% /opt/software

Page 64: Das kannste schon so machen

Filesystem Size Used Avail Use% Mounted on.../dev/mapper/datavg-lv_optsoftware 492G 22G 446G 5% /opt/software

Filesystem Inodes IUsed IFree IUse% Mounted on.../dev/mapper/datavg-lv_optsoftware 32768000 32428987 39013 99% /opt/software

Page 65: Das kannste schon so machen

Filesystem Size Used Avail Use% Mounted on.../dev/mapper/datavg-lv_optsoftware 492G 22G 446G 5% /opt/software

Filesystem Inodes IUsed IFree IUse% Mounted on.../dev/mapper/datavg-lv_optsoftware 32768000 32428987 39013 99% /opt/software

I lost track when the deepest node_modules pathwas about 2000 chars long…

Page 66: Das kannste schon so machen

npm dedupe would help,but only if npm install worked at least once…

Page 67: Das kannste schon so machen

Beware:Npm3 will be the default packagemanager starting with nodejs 5.x,and is a breaking change:

Page 68: Das kannste schon so machen

Lessons learned:We started the project when NodeJS 4.x and npm 3.xwere still unstable.That time is gone. Go for it.

Page 69: Das kannste schon so machen

Thank You!

André GoliathSenior Technical [email protected]