taming startup dynamics - magnus jungsbluth & domagoj cosic
TRANSCRIPT
125.10.2016
Taming Startup Dynamics
EclipseCon Europe 2016
Date: 2016-10-25Location: LudwigsburgAuthors: Magnus Jungsbluth | Domagoj Ćosić
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!");}
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
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
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)