Skip to content

Commit

Permalink
feat: Dagger refactor (#134)
Browse files Browse the repository at this point in the history
Signed-off-by: Alfredo Gutierrez <[email protected]>
  • Loading branch information
AlfredoG87 authored Aug 27, 2024
1 parent 587fac2 commit d00633e
Show file tree
Hide file tree
Showing 26 changed files with 799 additions and 228 deletions.
67 changes: 14 additions & 53 deletions server/src/main/java/com/hedera/block/server/BlockNodeApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,12 @@
import static java.lang.System.Logger;
import static java.lang.System.Logger.Level.INFO;

import com.hedera.block.server.config.BlockNodeContext;
import com.hedera.block.server.data.ObjectEvent;
import com.hedera.block.server.health.HealthService;
import com.hedera.block.server.mediator.LiveStreamMediatorBuilder;
import com.hedera.block.server.mediator.StreamMediator;
import com.hedera.block.server.persistence.storage.PersistenceStorageConfig;
import com.hedera.block.server.persistence.storage.read.BlockAsDirReaderBuilder;
import com.hedera.block.server.persistence.storage.read.BlockReader;
import com.hedera.block.server.persistence.storage.write.BlockAsDirWriterBuilder;
import com.hedera.block.server.persistence.storage.write.BlockWriter;
import com.hedera.hapi.block.SubscribeStreamResponse;
import com.hedera.hapi.block.stream.Block;
import com.hedera.hapi.block.stream.BlockItem;
import edu.umd.cs.findbugs.annotations.NonNull;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.WebServerConfig;
import io.helidon.webserver.grpc.GrpcRouting;
import io.helidon.webserver.grpc.GrpcService;
import io.helidon.webserver.http.HttpRouting;
import java.io.IOException;
import javax.inject.Inject;
Expand All @@ -51,23 +41,27 @@ public class BlockNodeApp {

private final ServiceStatus serviceStatus;
private final HealthService healthService;
private final BlockNodeContext blockNodeContext;
private final GrpcService blockStreamService;
private final WebServerConfig.Builder webServerBuilder;

/**
* Has all needed dependencies to start the server and initialize the context.
* Constructs a new BlockNodeApp with the specified dependencies.
*
* @param serviceStatus the status of the service
* @param healthService the health service
* @param blockNodeContext the context of the block node
* @param serviceStatus has the status of the service
* @param healthService handles the health API requests
* @param blockStreamService handles the GRPC API requests
* @param webServerBuilder used to build the web server and start it
*/
@Inject
public BlockNodeApp(
@NonNull ServiceStatus serviceStatus,
@NonNull HealthService healthService,
@NonNull BlockNodeContext blockNodeContext) {
@NonNull GrpcService blockStreamService,
@NonNull WebServerConfig.Builder webServerBuilder) {
this.serviceStatus = serviceStatus;
this.healthService = healthService;
this.blockNodeContext = blockNodeContext;
this.blockStreamService = blockStreamService;
this.webServerBuilder = webServerBuilder;
}

/**
Expand All @@ -77,23 +71,6 @@ public BlockNodeApp(
*/
public void start() throws IOException {

final BlockWriter<BlockItem> blockWriter =
BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build();
final StreamMediator<BlockItem, ObjectEvent<SubscribeStreamResponse>> streamMediator =
LiveStreamMediatorBuilder.newBuilder(blockWriter, blockNodeContext, serviceStatus)
.build();

final BlockReader<Block> blockReader =
BlockAsDirReaderBuilder.newBuilder(
blockNodeContext
.configuration()
.getConfigData(PersistenceStorageConfig.class))
.build();

final BlockStreamService blockStreamService =
buildBlockStreamService(
streamMediator, blockReader, serviceStatus, blockNodeContext);

final GrpcRouting.Builder grpcRouting = GrpcRouting.builder().service(blockStreamService);

final HttpRouting.Builder httpRouting =
Expand All @@ -102,11 +79,7 @@ public void start() throws IOException {
// Build the web server
// TODO: make port server a configurable value.
final WebServer webServer =
WebServer.builder()
.port(8080)
.addRouting(grpcRouting)
.addRouting(httpRouting)
.build();
webServerBuilder.port(8080).addRouting(grpcRouting).addRouting(httpRouting).build();

// Update the serviceStatus with the web server
serviceStatus.setWebServer(webServer);
Expand All @@ -117,16 +90,4 @@ public void start() throws IOException {
// Log the server status
LOGGER.log(INFO, String.format("Block Node Server started at port: %d", webServer.port()));
}

@NonNull
private static BlockStreamService buildBlockStreamService(
@NonNull
final StreamMediator<BlockItem, ObjectEvent<SubscribeStreamResponse>>
streamMediator,
@NonNull final BlockReader<Block> blockReader,
@NonNull final ServiceStatus serviceStatus,
@NonNull final BlockNodeContext blockNodeContext) {

return new BlockStreamService(streamMediator, blockReader, serviceStatus, blockNodeContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@

package com.hedera.block.server;

import com.hedera.block.server.config.ConfigInjectionModule;
import com.hedera.block.server.health.HealthInjectionModule;
import com.hedera.block.server.mediator.MediatorInjectionModule;
import com.hedera.block.server.metrics.MetricsInjectionModule;
import com.hedera.block.server.persistence.PersistenceInjectionModule;
import com.swirlds.config.api.Configuration;
import dagger.BindsInstance;
import dagger.Component;
import javax.inject.Singleton;

Expand All @@ -26,6 +32,10 @@
modules = {
BlockNodeAppInjectionModule.class,
HealthInjectionModule.class,
PersistenceInjectionModule.class,
MediatorInjectionModule.class,
ConfigInjectionModule.class,
MetricsInjectionModule.class,
})
public interface BlockNodeAppInjectionComponent {
/**
Expand All @@ -34,4 +44,19 @@ public interface BlockNodeAppInjectionComponent {
* @return the block node app server
*/
BlockNodeApp getBlockNodeApp();

/**
* Factory for the block node app injection component, needs a configuration to create the
* component and the block node app with all the wired dependencies.
*/
@Component.Factory
interface Factory {
/**
* Create the block node app injection component.
*
* @param configuration the configuration
* @return the block node app injection component
*/
BlockNodeAppInjectionComponent create(@BindsInstance Configuration configuration);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package com.hedera.block.server;

import com.hedera.block.server.config.BlockNodeContext;
import com.hedera.block.server.config.BlockNodeContextFactory;
import com.hedera.block.server.metrics.MetricsService;
import com.swirlds.config.api.Configuration;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import java.io.IOException;
import io.helidon.webserver.WebServerConfig;
import io.helidon.webserver.grpc.GrpcService;
import javax.inject.Singleton;

/**
Expand All @@ -42,17 +44,37 @@ public interface BlockNodeAppInjectionModule {
ServiceStatus bindServiceStatus(ServiceStatusImpl serviceStatus);

/**
* Provides a block node context singleton using the factory.
* Provides a block node context singleton.
*
* @param config should come from DI
* @param metricsService should come from DI
* @return a block node context singleton
*/
@Singleton
@Provides
static BlockNodeContext provideBlockNodeContext(
Configuration config, MetricsService metricsService) {
return new BlockNodeContext(metricsService, config);
}

/**
* Provides a block stream service singleton using DI.
*
* @param blockStreamService should come from DI
* @return a block stream service singleton
*/
@Singleton
static BlockNodeContext provideBlockNodeContext() {
try {
return BlockNodeContextFactory.create();
} catch (IOException e) {
throw new RuntimeException(e);
}
@Binds
GrpcService bindBlockStreamService(BlockStreamService blockStreamService);

/**
* Provides a web server config builder singleton using DI.
*
* @return a web server config builder singleton
*/
@Singleton
@Provides
static WebServerConfig.Builder provideWebServerConfigBuilder() {
return WebServerConfig.builder();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import java.io.IOException;
import java.time.Clock;
import java.util.Optional;
import javax.inject.Inject;

/**
* The BlockStreamService class defines the gRPC service for the block stream service. It provides
Expand All @@ -76,6 +77,7 @@ public class BlockStreamService implements GrpcService {
* @param serviceStatus the service status provides methods to check service availability and to
* stop the service and web server in the event of an unrecoverable exception
*/
@Inject
BlockStreamService(
@NonNull
final StreamMediator<BlockItem, ObjectEvent<SubscribeStreamResponse>>
Expand Down
3 changes: 3 additions & 0 deletions server/src/main/java/com/hedera/block/server/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
public final class Constants {
private Constants() {}

/** Constant mapped to the application.properties file in resources with default values */
@NonNull public static final String APPLICATION_PROPERTIES = "app.properties";

/** Constant mapped to the name of the service in the .proto file */
@NonNull public static final String SERVICE_NAME = "BlockStreamService";

Expand Down
24 changes: 23 additions & 1 deletion server/src/main/java/com/hedera/block/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@
import static java.lang.System.Logger;
import static java.lang.System.Logger.Level.INFO;

import com.swirlds.config.api.Configuration;
import com.swirlds.config.api.ConfigurationBuilder;
import com.swirlds.config.extensions.sources.ClasspathFileConfigSource;
import com.swirlds.config.extensions.sources.SystemEnvironmentConfigSource;
import com.swirlds.config.extensions.sources.SystemPropertiesConfigSource;
import java.io.IOException;
import java.nio.file.Path;

/** Main class for the block node server */
public class Server {
Expand All @@ -36,8 +42,24 @@ private Server() {}
*/
public static void main(final String[] args) throws IOException {
LOGGER.log(INFO, "Starting BlockNode Server");

// Init BlockNode Configuration
Configuration configuration =
ConfigurationBuilder.create()
.withSource(SystemEnvironmentConfigSource.getInstance())
.withSource(SystemPropertiesConfigSource.getInstance())
.withSource(
new ClasspathFileConfigSource(
Path.of(Constants.APPLICATION_PROPERTIES)))
.autoDiscoverExtensions()
.build();

// Init Dagger DI Component, passing in the configuration.
// this is where all the dependencies are wired up (magic happens)
final BlockNodeAppInjectionComponent daggerComponent =
DaggerBlockNodeAppInjectionComponent.create();
DaggerBlockNodeAppInjectionComponent.factory().create(configuration);

// Use Dagger DI Component to start the BlockNodeApp with all wired dependencies
final BlockNodeApp blockNodeApp = daggerComponent.getBlockNodeApp();
blockNodeApp.start();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.google.auto.service.AutoService;
import com.hedera.block.server.consumer.ConsumerConfig;
import com.hedera.block.server.persistence.storage.PersistenceStorageConfig;
import com.swirlds.common.config.BasicCommonConfig;
import com.swirlds.common.metrics.config.MetricsConfig;
import com.swirlds.common.metrics.platform.prometheus.PrometheusConfig;
import com.swirlds.config.api.ConfigurationExtension;
Expand All @@ -44,7 +43,6 @@ public BlockNodeConfigExtension() {
@Override
public Set<Class<? extends Record>> getConfigDataTypes() {
return Set.of(
BasicCommonConfig.class,
MetricsConfig.class,
PrometheusConfig.class,
ConsumerConfig.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,14 @@

import com.hedera.block.server.metrics.MetricsService;
import com.swirlds.config.api.Configuration;
import com.swirlds.metrics.api.Metrics;
import edu.umd.cs.findbugs.annotations.NonNull;

/**
* Context for the block node. This record is returned by the BlockNodeContextFactory when a new
* configuration is created.
*
* @param metrics the metrics used for monitoring and reporting
* @param metricsService the service responsible for handling metrics
* @param configuration the configuration settings for the block node
*/
public record BlockNodeContext(
@NonNull Metrics metrics,
@NonNull MetricsService metricsService,
@NonNull Configuration configuration) {}
@NonNull MetricsService metricsService, @NonNull Configuration configuration) {}
Loading

0 comments on commit d00633e

Please sign in to comment.