19
1 25.10.2016 Taming Startup Dynamics EclipseCon Europe 2016 Date: 2016-10-25 Location: Ludwigsburg Authors: Magnus Jungsbluth | Domagoj Ćosić

Taming startup dynamics - Magnus Jungsbluth & Domagoj Cosic

Embed Size (px)

Citation preview

125.10.2016

Taming Startup Dynamics

EclipseCon Europe 2016

Date: 2016-10-25Location: LudwigsburgAuthors: Magnus Jungsbluth | Domagoj Ćosić

225.10.2016

Taming Startup Dynamics

We love OSGi dynamics

325.10.2016

Taming Startup Dynamics

BUT sometimes you need something predictable System startup Partial restart Re-configurations that must succeed Integration tests expect system in a stable state

425.10.2016

Taming Startup Dynamics

We… … operate national eID infrastructure … operate a Trust Center on premises … operate the Public Key Directory for the ICAO

525.10.2016

Taming Startup Dynamics

What we want Any error during startup ⇒ shutdown immediately In any trade-off that has security on one side, favor that side Open network ports iff all sub-systems report success Unmanned reboots shouldn’t pose a threat

625.10.2016

Example of what is broken

CountDownLatch latch = new CountDownLatch(1);AtomicReference<Throwable> error = new AtomicReference<>();framework.adapt(FrameworkStartLevel.class).setStartLevel(10, new FrameworkListener() { @Override public void frameworkEvent(final FrameworkEvent event) { if (event.getType() == FrameworkEvent.STARTLEVEL_CHANGED) { latch.countDown(); } else if (event.getType() == FrameworkEvent.ERROR) { error.set(event.getCause()); latch.countDown(); } } });latch.await();

if (error.get() != null) { System.out.println("SUCCESS!?"); // ... and what about DS + Blueprint // + ConfigAdmin (Asynchronous after BundleEvent.ACTIVE) ?}

725.10.2016

How it could look like

AtomicBoolean systemStarted = new AtomicBoolean();CountDownLatch latch = new CountDownLatch(1);framework.adapt(FrameworkStartLevel.class).setStartLevel(10);

framework.registerService(SystemStartupListener.class, new SystemStartupListener() { @Override public void systemStartedEvent(SystemStartedEvent event) { systemStarted.set(event.getType() == SystemStartedEvent.SYSTEM_STARTED); latch.countDown(); } });

latch.await();

if (systemStarted.get()) { System.out.println("SUCCESS!");}

825.10.2016

Taming Startup Dynamics

- Live demonstration -

925.10.2016

Parts of our solution (1)

StartupMonitorReport state for one sub-systemSystemStartupControllerCollect state and send eventsSystemStartupListenerReceive live events or event playbackStartPhaseHigher level concept over start levels

1025.10.2016

Parts of our solution (2)

1125.10.2016

High level overview

Start Launcher Framework starts to highest startlevel of phase 1

Phase 1 (wait for FrameworkEvent): wait until all startup monitors signal success increase start level to highest start level of next phase

...

Phase N (wait for FrameworkEvent): wait until all startup monitors signal success signal successful system startup

1225.10.2016

Start Phases

SYSTEMHandle low-level stuff, make sure db schemas are migrated, … APPLICATIONConfigure everything that makes the app runADMINOpen network ports used for administrative purposes, start scheduler, thread poolsPUBLICOpen up all public network ports

1325.10.2016

Taming Startup Dynamics

Covered sub-systems Successful Bundle resolution Blueprint Configuration Admin

1425.10.2016

Anatomy of a StartupMonitor (1)

public class MyStartupMonitor implements StartupMonitor<T> { StartupMonitorState<T> prepareMonitoredItems(StartupPhase phase) { unfinishedItems = //gather erroneousItems = //empty set latch = new CountDownLatch(unfinishedItems.size()); }

//code that does the monitoring and decrements latch on changes

StartupMonitorState<T> waitForResult(long timeout, TimeUnit unit) { boolean finished = latch.await(timeout, unit); return new MyState(finished, unfinishedItems, erroneousItems); }

private class MyState implements StartupMonitorState<T> { // cont. in the next slide }}

1525.10.2016

Anatomy of a StartupMonitor (2)

private class MyState implements StartupMonitorState<T> {

...

void buildRepresentation(T item, StateRepresentationBuilder representation) {

representation

.show(item.getProperty()).reason(item.getCause())

.details().

.show(...).reason(...);

}

}

1625.10.2016

Taming Startup Dynamics

Other gimicks: Can wait on successful application of configuration (aka the missing

ConfigurationEvent) ManagedService(Factory) can define service dependencies (i.e. a DataSource) that

depend on a particular configuration property’s value (i.e. a datasource id) Supervised shutdown

1725.10.2016

Taming Startup Dynamics

Questions ?

1825.10.2016

1925.10.2016

Please note: This presentation is the property of Bundesdruckerei GmbH. All of the information contained herein may not be copied, distributed or published, as a whole or in part, without the approval of Bundesdruckerei GmbH. Copyright 2016 Bundesdruckerei GmbH

Disclaimer

Magnus Jungsbluth | Domagoj ĆosićE-Mail: [email protected] | [email protected]: +49 (30) 2598 – (3671|3635)