Skip to content

Commit c54e655

Browse files
concrete > refactor bootstrapping
1 parent 32b6f89 commit c54e655

14 files changed

+552
-305
lines changed
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
package com.hivemq;
2+
3+
import com.codahale.metrics.MetricRegistry;
4+
import com.google.common.base.Preconditions;
5+
import com.hivemq.api.resources.GenericAPIHolder;
6+
import com.hivemq.bootstrap.HiveMQExceptionHandlerBootstrap;
7+
import com.hivemq.bootstrap.LoggingBootstrap;
8+
import com.hivemq.bootstrap.ioc.DaggerInjector;
9+
import com.hivemq.bootstrap.ioc.Injector;
10+
import com.hivemq.bootstrap.ioc.Persistences;
11+
import com.hivemq.bootstrap.services.CompleteBootstrapService;
12+
import com.hivemq.bootstrap.services.CompleteBootstrapServiceImpl;
13+
import com.hivemq.bootstrap.services.GeneralBootstrapServiceImpl;
14+
import com.hivemq.bootstrap.services.PersistenceBootstrapService;
15+
import com.hivemq.bootstrap.services.PersistenceBootstrapServiceImpl;
16+
import com.hivemq.common.shutdown.ShutdownHooks;
17+
import com.hivemq.configuration.ConfigurationBootstrap;
18+
import com.hivemq.configuration.info.SystemInformation;
19+
import com.hivemq.configuration.service.ConfigurationService;
20+
import com.hivemq.edge.HiveMQCapabilityService;
21+
import com.hivemq.edge.impl.capability.CapabilityServiceImpl;
22+
import com.hivemq.edge.modules.ModuleLoader;
23+
import com.hivemq.exceptions.HiveMQEdgeStartupException;
24+
import com.hivemq.extension.sdk.api.annotations.NotNull;
25+
import com.hivemq.extension.sdk.api.annotations.Nullable;
26+
import com.hivemq.extensions.core.CommercialModuleLoaderDiscovery;
27+
import com.hivemq.extensions.core.HandlerService;
28+
import com.hivemq.extensions.core.PersistencesService;
29+
import com.hivemq.extensions.core.RestComponentsService;
30+
import com.hivemq.extensions.core.RestComponentsServiceImpl;
31+
import com.hivemq.metrics.MetricRegistryLogger;
32+
import com.hivemq.persistence.PersistenceStartup;
33+
import com.hivemq.persistence.connection.ConnectionPersistence;
34+
import com.hivemq.persistence.connection.ConnectionPersistenceImpl;
35+
import org.apache.commons.io.FileUtils;
36+
import org.slf4j.Logger;
37+
import org.slf4j.LoggerFactory;
38+
39+
import java.io.File;
40+
import java.io.IOException;
41+
import java.util.Objects;
42+
43+
public class HiveMQEdgeBootstrap {
44+
45+
private static final @NotNull Logger log = LoggerFactory.getLogger(HiveMQEdgeBootstrap.class);
46+
47+
private final @NotNull MetricRegistry metricRegistry;
48+
private final @NotNull SystemInformation systemInformation;
49+
private final @NotNull ModuleLoader moduleLoader;
50+
private @Nullable ConfigurationService configService;
51+
52+
private final @NotNull PersistenceStartup persistenceStartup = new PersistenceStartup();
53+
private final @NotNull HandlerService handlerService = new HandlerService();
54+
private final @NotNull GenericAPIHolder genericAPIHolder = new GenericAPIHolder();
55+
private final @NotNull ShutdownHooks shutdownHooks = new ShutdownHooks();
56+
private final @NotNull HiveMQCapabilityService capabilityService = new CapabilityServiceImpl();
57+
private final @NotNull ConnectionPersistence connectionPersistence = new ConnectionPersistenceImpl();
58+
private final @NotNull PersistencesService persistencesService = new PersistencesService(persistenceStartup);
59+
private final @NotNull RestComponentsService restComponentsService =
60+
new RestComponentsServiceImpl(genericAPIHolder);
61+
private @Nullable CommercialModuleLoaderDiscovery commercialModuleLoaderDiscovery;
62+
private @Nullable GeneralBootstrapServiceImpl generalBootstrapService;
63+
private @Nullable PersistenceBootstrapService persistenceBootstrapService;
64+
private @Nullable Injector injector;
65+
66+
public HiveMQEdgeBootstrap(
67+
final @NotNull MetricRegistry metricRegistry,
68+
final @NotNull SystemInformation systemInformation,
69+
final @NotNull ModuleLoader moduleLoader,
70+
final @Nullable ConfigurationService configService) {
71+
this.metricRegistry = metricRegistry;
72+
this.systemInformation = systemInformation;
73+
this.moduleLoader = moduleLoader;
74+
this.configService = configService;
75+
}
76+
77+
public @NotNull Injector bootstrap() throws HiveMQEdgeStartupException {
78+
metricRegistry.addListener(new MetricRegistryLogger());
79+
80+
LoggingBootstrap.prepareLogging();
81+
82+
// Embedded has already called init as it is required to read the config file.
83+
if (!systemInformation.isEmbedded()) {
84+
log.trace("Initializing HiveMQ home directory");
85+
//Create SystemInformation this early because logging depends on it
86+
systemInformation.init();
87+
}
88+
89+
log.trace("Initializing Logging");
90+
LoggingBootstrap.initLogging(systemInformation.getConfigFolder());
91+
92+
log.trace("Initializing Exception handlers");
93+
HiveMQExceptionHandlerBootstrap.addUnrecoverableExceptionHandler();
94+
95+
//ungraceful shutdown does not delete tmp folders, so we clean them up on broker start
96+
log.trace("Cleaning up temporary folders");
97+
deleteTmpFolder(systemInformation.getDataFolder());
98+
99+
bootstrapCoreComponents();
100+
101+
if (configService == null) {
102+
log.trace("Initializing configuration");
103+
configService = ConfigurationBootstrap.bootstrapConfig(systemInformation);
104+
}
105+
bootstrapInjector();
106+
final long startInit = System.currentTimeMillis();
107+
108+
bootstrapPersistences();
109+
110+
// make sure all persistences are bootstrapped.
111+
awaitPersistenceStartup();
112+
113+
finishBootstrap();
114+
115+
log.trace("Initializing classes");
116+
Objects.requireNonNull(injector).initEagerSingletons();
117+
log.trace("Initialized classes in {}ms", (System.currentTimeMillis() - startInit));
118+
return injector;
119+
}
120+
121+
private void awaitPersistenceStartup() {
122+
Objects.requireNonNull(injector).persistences();
123+
try {
124+
persistenceStartup.finish();
125+
} catch (InterruptedException e) {
126+
throw new HiveMQEdgeStartupException(e);
127+
}
128+
129+
// configService is always set in caller
130+
assert configService != null;
131+
132+
log.info("HiveMQ Edge starts with Persistence Mode: '{}'",
133+
configService.persistenceConfigurationService().getMode());
134+
}
135+
136+
private void bootstrapInjector() {
137+
log.trace("Initializing injector");
138+
final long startDagger = System.currentTimeMillis();
139+
injector = DaggerInjector.builder()
140+
.configurationService(configService)
141+
.systemInformation(systemInformation)
142+
.metricRegistry(metricRegistry)
143+
.persistenceService(persistencesService)
144+
.handlerService(handlerService)
145+
.persistenceStartUp(persistenceStartup)
146+
.moduleLoader(moduleLoader)
147+
.shutdownHooks(shutdownHooks)
148+
.capabilityService(capabilityService)
149+
.restComponentService(restComponentsService)
150+
.restComponentsHolder(genericAPIHolder)
151+
.connectionPersistence(connectionPersistence)
152+
.build();
153+
log.trace("Initialized injector in {}ms", (System.currentTimeMillis() - startDagger));
154+
}
155+
156+
private void bootstrapCoreComponents() {
157+
log.info("Integrating Core Modules");
158+
// configService is always set in caller
159+
assert configService != null;
160+
161+
162+
try {
163+
commercialModuleLoaderDiscovery = new CommercialModuleLoaderDiscovery(moduleLoader);
164+
commercialModuleLoaderDiscovery.discoverModuleLoaderMainClasses();
165+
generalBootstrapService = new GeneralBootstrapServiceImpl(shutdownHooks, metricRegistry, systemInformation);
166+
commercialModuleLoaderDiscovery.generalBootstrap(generalBootstrapService);
167+
} catch (Exception e) {
168+
log.warn("Error on loading the commercial module loader.", e);
169+
throw new HiveMQEdgeStartupException(e);
170+
}
171+
}
172+
173+
174+
private void bootstrapPersistences() {
175+
Preconditions.checkNotNull(generalBootstrapService);
176+
Preconditions.checkNotNull(configService);
177+
Preconditions.checkNotNull(commercialModuleLoaderDiscovery);
178+
179+
try {
180+
persistenceBootstrapService = PersistenceBootstrapServiceImpl.decorate(generalBootstrapService,
181+
configService,
182+
persistencesService,
183+
capabilityService);
184+
commercialModuleLoaderDiscovery.persistenceBootstrap(persistenceBootstrapService);
185+
} catch (Exception e) {
186+
log.warn("Error on bootstrapping persistences.", e);
187+
throw new HiveMQEdgeStartupException(e);
188+
}
189+
}
190+
191+
private void finishBootstrap() {
192+
Preconditions.checkNotNull(injector);
193+
final Persistences persistences = injector.persistences();
194+
Preconditions.checkNotNull(persistences);
195+
Preconditions.checkNotNull(configService);
196+
Preconditions.checkNotNull(commercialModuleLoaderDiscovery);
197+
Preconditions.checkNotNull(persistenceBootstrapService);
198+
199+
try {
200+
final CompleteBootstrapService completeBootstrapService = CompleteBootstrapServiceImpl.decorate(
201+
persistenceBootstrapService,
202+
persistences,
203+
restComponentsService,
204+
handlerService);
205+
commercialModuleLoaderDiscovery.completeBootstrap(completeBootstrapService);
206+
} catch (Exception e) {
207+
log.warn("Error on bootstraping persistences.", e);
208+
throw new HiveMQEdgeStartupException(e);
209+
}
210+
}
211+
212+
213+
private static void deleteTmpFolder(final @NotNull File dataFolder) {
214+
final String tmpFolder = dataFolder.getPath() + File.separator + "tmp";
215+
try {
216+
//ungraceful shutdown does not delete tmp folders, so we clean them up on broker start
217+
FileUtils.deleteDirectory(new File(tmpFolder));
218+
} catch (IOException e) {
219+
//No error because it's not business breaking
220+
log.warn("The temporary folder could not be deleted ({}).", tmpFolder);
221+
if (log.isDebugEnabled()) {
222+
log.debug("Original Exception: ", e);
223+
}
224+
}
225+
}
226+
227+
}

hivemq-edge/src/main/java/com/hivemq/HiveMQEdgeMain.java

Lines changed: 4 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,22 @@
1717

1818
import com.codahale.metrics.MetricFilter;
1919
import com.codahale.metrics.MetricRegistry;
20-
import com.hivemq.api.resources.GenericAPIHolder;
21-
import com.hivemq.bootstrap.HiveMQExceptionHandlerBootstrap;
2220
import com.hivemq.bootstrap.LoggingBootstrap;
23-
import com.hivemq.bootstrap.ioc.DaggerInjector;
2421
import com.hivemq.bootstrap.ioc.Injector;
2522
import com.hivemq.common.shutdown.ShutdownHooks;
26-
import com.hivemq.configuration.ConfigurationBootstrap;
2723
import com.hivemq.configuration.info.SystemInformation;
2824
import com.hivemq.configuration.info.SystemInformationImpl;
2925
import com.hivemq.configuration.service.ApiConfigurationService;
3026
import com.hivemq.configuration.service.ConfigurationService;
31-
import com.hivemq.edge.HiveMQCapabilityService;
32-
import com.hivemq.edge.impl.capability.CapabilityServiceImpl;
3327
import com.hivemq.edge.modules.ModuleLoader;
3428
import com.hivemq.embedded.EmbeddedExtension;
3529
import com.hivemq.exceptions.HiveMQEdgeStartupException;
3630
import com.hivemq.extension.sdk.api.annotations.NotNull;
3731
import com.hivemq.extension.sdk.api.annotations.Nullable;
38-
import com.hivemq.extensions.core.CommercialModuleLoaderDiscovery;
39-
import com.hivemq.extensions.core.CoreModuleServiceImpl;
40-
import com.hivemq.extensions.core.HandlerService;
41-
import com.hivemq.extensions.core.PersistencesService;
42-
import com.hivemq.extensions.core.RestComponentsService;
43-
import com.hivemq.extensions.core.RestComponentsServiceImpl;
4432
import com.hivemq.http.JaxrsHttpServer;
45-
import com.hivemq.metrics.MetricRegistryLogger;
46-
import com.hivemq.persistence.PersistenceStartup;
47-
import com.hivemq.persistence.connection.ConnectionPersistence;
48-
import com.hivemq.persistence.connection.ConnectionPersistenceImpl;
49-
import org.apache.commons.io.FileUtils;
5033
import org.slf4j.Logger;
5134
import org.slf4j.LoggerFactory;
5235

53-
import java.io.File;
54-
import java.io.IOException;
5536
import java.util.Objects;
5637
import java.util.concurrent.TimeUnit;
5738

@@ -62,7 +43,6 @@ public class HiveMQEdgeMain {
6243
private final @NotNull ModuleLoader moduleLoader;
6344
private final @NotNull MetricRegistry metricRegistry;
6445
private final @NotNull SystemInformation systemInformation;
65-
private final @NotNull PersistenceStartup persistenceStartup = new PersistenceStartup();
6646

6747
private @Nullable JaxrsHttpServer jaxrsServer;
6848

@@ -85,95 +65,12 @@ public void bootstrap() throws HiveMQEdgeStartupException {
8565
if (injector != null) {
8666
return;
8767
}
88-
89-
metricRegistry.addListener(new MetricRegistryLogger());
90-
91-
LoggingBootstrap.prepareLogging();
92-
93-
// Embedded has already called init as it is required to read the config file.
94-
if (!systemInformation.isEmbedded()) {
95-
log.trace("Initializing HiveMQ home directory");
96-
//Create SystemInformation this early because logging depends on it
97-
systemInformation.init();
98-
}
99-
100-
log.trace("Initializing Logging");
101-
LoggingBootstrap.initLogging(systemInformation.getConfigFolder());
102-
103-
log.trace("Initializing Exception handlers");
104-
HiveMQExceptionHandlerBootstrap.addUnrecoverableExceptionHandler();
105-
106-
if (configService == null) {
107-
log.trace("Initializing configuration");
108-
configService = ConfigurationBootstrap.bootstrapConfig(systemInformation);
109-
}
110-
111-
//ungraceful shutdown does not delete tmp folders, so we clean them up on broker start
112-
log.trace("Cleaning up temporary folders");
113-
deleteTmpFolder(systemInformation.getDataFolder());
114-
115-
log.info("Integrating Core Modules");
116-
final PersistencesService persistencesService = new PersistencesService(persistenceStartup);
117-
final HandlerService handlerService = new HandlerService();
118-
final GenericAPIHolder genericAPIHolder = new GenericAPIHolder();
119-
final RestComponentsService restComponentsService = new RestComponentsServiceImpl(genericAPIHolder);
120-
final ShutdownHooks shutdownHooks = new ShutdownHooks();
121-
final HiveMQCapabilityService capabilityService = new CapabilityServiceImpl();
122-
final ConnectionPersistence connectionPersistence = new ConnectionPersistenceImpl();
123-
124-
CoreModuleServiceImpl coreModuleService = new CoreModuleServiceImpl(persistencesService,
125-
systemInformation,
126-
metricRegistry,
127-
shutdownHooks,
128-
moduleLoader,
129-
configService,
130-
capabilityService,
131-
restComponentsService, handlerService, connectionPersistence);
132-
133-
try {
134-
final CommercialModuleLoaderDiscovery commercialModuleLoaderDiscovery = new CommercialModuleLoaderDiscovery(
135-
moduleLoader,
136-
coreModuleService);
137-
commercialModuleLoaderDiscovery.loadAllCoreModules();
138-
} catch (Exception e) {
139-
log.warn("Error on loading the commercial module loader.", e);
140-
throw new HiveMQEdgeStartupException(e);
141-
}
142-
143-
log.trace("Initializing injector");
144-
final long startDagger = System.currentTimeMillis();
145-
injector = DaggerInjector.builder()
146-
.configurationService(configService)
147-
.systemInformation(systemInformation)
148-
.metricRegistry(metricRegistry)
149-
.persistenceService(persistencesService)
150-
.handlerService(handlerService)
151-
.persistenceStartUp(persistenceStartup)
152-
.moduleLoader(moduleLoader)
153-
.shutdownHooks(shutdownHooks)
154-
.capabilityService(capabilityService)
155-
.restComponentService(restComponentsService)
156-
.restComponentsHolder(genericAPIHolder).coreModuleService(coreModuleService)
157-
.connectionPersistence(connectionPersistence)
158-
.build();
159-
log.trace("Initialized injector in {}ms", (System.currentTimeMillis() - startDagger));
160-
injector.persistences();
161-
final long startInit = System.currentTimeMillis();
162-
Objects.requireNonNull(injector).persistences();
163-
try {
164-
persistenceStartup.finish();
165-
} catch (InterruptedException e) {
166-
throw new HiveMQEdgeStartupException(e);
167-
}
168-
log.info("HiveMQ Edge starts with Persistence Mode: '{}'",
169-
configService.persistenceConfigurationService().getMode());
170-
171-
log.trace("Initializing classes");
172-
Objects.requireNonNull(injector).initEagerSingletons();
173-
log.trace("Initialized classes in {}ms", (System.currentTimeMillis() - startInit));
174-
68+
final HiveMQEdgeBootstrap bootstrap =
69+
new HiveMQEdgeBootstrap(metricRegistry, systemInformation, moduleLoader, configService);
70+
injector = bootstrap.bootstrap();
17571
}
17672

73+
17774
protected void startGateway(final @Nullable EmbeddedExtension embeddedExtension) throws HiveMQEdgeStartupException {
17875
if (injector == null) {
17976
throw new HiveMQEdgeStartupException("invalid startup state");
@@ -274,18 +171,5 @@ public static void main(final String @NotNull [] args) throws Exception {
274171
return injector;
275172
}
276173

277-
private static void deleteTmpFolder(final @NotNull File dataFolder) {
278-
final String tmpFolder = dataFolder.getPath() + File.separator + "tmp";
279-
try {
280-
//ungraceful shutdown does not delete tmp folders, so we clean them up on broker start
281-
FileUtils.deleteDirectory(new File(tmpFolder));
282-
} catch (IOException e) {
283-
//No error because it's not business breaking
284-
log.warn("The temporary folder could not be deleted ({}).", tmpFolder);
285-
if (log.isDebugEnabled()) {
286-
log.debug("Original Exception: ", e);
287-
}
288-
}
289-
}
290174

291175
}

0 commit comments

Comments
 (0)