Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Dagger refactor #134

Merged
merged 17 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
cedb64d
Injecting BlockWriter as part of PersistenInjectionModule
AlfredoG87 Aug 24, 2024
31eddb9
Refactoring everything at BlockNodeApp to use Dagger singletons inste…
AlfredoG87 Aug 24, 2024
e945fb1
Improving test and including missing java docs
AlfredoG87 Aug 24, 2024
58b61a7
bringing back mock needed for test
AlfredoG87 Aug 24, 2024
41db6ca
started refactor of BlockNodeContextFactory and BlockNodeContext, is …
AlfredoG87 Aug 24, 2024
3f563f3
Fixed UT for existing tests, ContextFactory is just a Shell, we shoul…
AlfredoG87 Aug 25, 2024
a00e0b3
fixing warnings
AlfredoG87 Aug 25, 2024
f9b69e2
Got rid of the BlockNodeContextFactory, next step, probably for a fut…
AlfredoG87 Aug 25, 2024
883969c
fixed javadocs and exported metrics to remove warning
AlfredoG87 Aug 25, 2024
30cda24
Refactor BlockNodeAppInjectionComponent to need an external configura…
AlfredoG87 Aug 25, 2024
99aa01f
Moved PersistenceInjectionModule to persistance package instead of pe…
AlfredoG87 Aug 25, 2024
1b2690c
Added UT for PersistenceInjectionModule
AlfredoG87 Aug 25, 2024
689b6fc
Added UT for missing InjectionModules, removed unneeded configuration…
AlfredoG87 Aug 25, 2024
56af241
Last UT to complete coverage
AlfredoG87 Aug 25, 2024
86ac482
Settling for Factory instead of Builder when passing the configuration
AlfredoG87 Aug 26, 2024
15076c5
Refactored GrpcProvider dagger bean to use the interface instead of t…
AlfredoG87 Aug 26, 2024
020dd92
Moved Application_Properties file to Constants
AlfredoG87 Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading