From cedb64dfe64890d6bb53409f036c98ac05802a7c Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 10:23:07 -0600 Subject: [PATCH 01/17] Injecting BlockWriter as part of PersistenInjectionModule Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/BlockNodeApp.java | 12 +++-- .../BlockNodeAppInjectionComponent.java | 2 + .../storage/PersistenceInjectionModule.java | 48 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java index 58b668ed..2bc644bc 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java @@ -27,7 +27,6 @@ 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; @@ -52,6 +51,7 @@ public class BlockNodeApp { private final ServiceStatus serviceStatus; private final HealthService healthService; private final BlockNodeContext blockNodeContext; + private final BlockWriter blockWriter; /** * Has all needed dependencies to start the server and initialize the context. @@ -59,15 +59,18 @@ public class BlockNodeApp { * @param serviceStatus the status of the service * @param healthService the health service * @param blockNodeContext the context of the block node + * @param blockWriter the block writer */ @Inject public BlockNodeApp( @NonNull ServiceStatus serviceStatus, @NonNull HealthService healthService, - @NonNull BlockNodeContext blockNodeContext) { + @NonNull BlockNodeContext blockNodeContext, + BlockWriter blockWriter) { this.serviceStatus = serviceStatus; this.healthService = healthService; this.blockNodeContext = blockNodeContext; + this.blockWriter = blockWriter; } /** @@ -77,8 +80,9 @@ public BlockNodeApp( */ public void start() throws IOException { - final BlockWriter blockWriter = - BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build(); + // final BlockWriter blockWriter = + // BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build(); + final StreamMediator> streamMediator = LiveStreamMediatorBuilder.newBuilder(blockWriter, blockNodeContext, serviceStatus) .build(); diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index b429b4e8..5e050eff 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -17,6 +17,7 @@ package com.hedera.block.server; import com.hedera.block.server.health.HealthInjectionModule; +import com.hedera.block.server.persistence.storage.PersistenceInjectionModule; import dagger.Component; import javax.inject.Singleton; @@ -26,6 +27,7 @@ modules = { BlockNodeAppInjectionModule.class, HealthInjectionModule.class, + PersistenceInjectionModule.class }) public interface BlockNodeAppInjectionComponent { /** diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java new file mode 100644 index 00000000..5b3a940b --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.persistence.storage; + +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.persistence.storage.write.BlockAsDirWriterBuilder; +import com.hedera.block.server.persistence.storage.write.BlockWriter; +import com.hedera.hapi.block.stream.BlockItem; +import dagger.Module; +import dagger.Provides; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; +import javax.inject.Singleton; + +/** A Dagger module for providing dependencies for Persistence Module. */ +@Module +public interface PersistenceInjectionModule { + + /** + * Provides a block writer singleton using the block node context. + * + * @param blockNodeContext the application context + * @return a block writer singleton + */ + @Provides + @Singleton + static BlockWriter providesBlockWriter(@NonNull BlockNodeContext blockNodeContext) { + try { + return BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build(); + } catch (IOException e) { + throw new RuntimeException("Failed to create block writer", e); + } + } +} From 31eddb9bc6bbc82719ea23c7479e9af95a14b5da Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 13:58:15 -0600 Subject: [PATCH 02/17] Refactoring everything at BlockNodeApp to use Dagger singletons instead injected at the constructor by DaggerComponent, instead of initializing them on the startup sequence. Also, adding a BlockNodeApp Test now that everything is being injected. Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/BlockNodeApp.java | 62 ++----------- .../BlockNodeAppInjectionComponent.java | 6 +- .../server/BlockNodeAppInjectionModule.java | 28 +++++- .../block/server/BlockStreamService.java | 2 + .../server/config/ConfigInjectionModule.java | 86 +++++++++++++++++++ .../mediator/MediatorInjectionModule.java | 51 +++++++++++ .../storage/PersistenceInjectionModule.java | 9 ++ .../hedera/block/server/BlockNodeAppTest.java | 76 ++++++++++++++++ 8 files changed, 264 insertions(+), 56 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java create mode 100644 server/src/main/java/com/hedera/block/server/mediator/MediatorInjectionModule.java create mode 100644 server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java index 2bc644bc..5b0b8a9f 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java @@ -19,20 +19,10 @@ 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.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.http.HttpRouting; import java.io.IOException; @@ -50,27 +40,25 @@ public class BlockNodeApp { private final ServiceStatus serviceStatus; private final HealthService healthService; - private final BlockNodeContext blockNodeContext; - private final BlockWriter blockWriter; + private final BlockStreamService blockStreamService; + private final WebServerConfig.Builder webServerBuilder; /** * Has all needed dependencies to start the server and initialize the context. * * @param serviceStatus the status of the service * @param healthService the health service - * @param blockNodeContext the context of the block node - * @param blockWriter the block writer */ @Inject public BlockNodeApp( @NonNull ServiceStatus serviceStatus, @NonNull HealthService healthService, - @NonNull BlockNodeContext blockNodeContext, - BlockWriter blockWriter) { + @NonNull BlockStreamService blockStreamService, + @NonNull WebServerConfig.Builder webServerBuilder) { this.serviceStatus = serviceStatus; this.healthService = healthService; - this.blockNodeContext = blockNodeContext; - this.blockWriter = blockWriter; + this.blockStreamService = blockStreamService; + this.webServerBuilder = webServerBuilder; } /** @@ -80,24 +68,6 @@ public BlockNodeApp( */ public void start() throws IOException { - // final BlockWriter blockWriter = - // BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build(); - - final StreamMediator> streamMediator = - LiveStreamMediatorBuilder.newBuilder(blockWriter, blockNodeContext, serviceStatus) - .build(); - - final BlockReader 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 = @@ -106,11 +76,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); @@ -121,16 +87,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> - streamMediator, - @NonNull final BlockReader blockReader, - @NonNull final ServiceStatus serviceStatus, - @NonNull final BlockNodeContext blockNodeContext) { - - return new BlockStreamService(streamMediator, blockReader, serviceStatus, blockNodeContext); - } } diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index 5e050eff..8f8e91a4 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -16,7 +16,9 @@ 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.persistence.storage.PersistenceInjectionModule; import dagger.Component; import javax.inject.Singleton; @@ -27,7 +29,9 @@ modules = { BlockNodeAppInjectionModule.class, HealthInjectionModule.class, - PersistenceInjectionModule.class + PersistenceInjectionModule.class, + MediatorInjectionModule.class, + ConfigInjectionModule.class }) public interface BlockNodeAppInjectionComponent { /** diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index 5a5b076e..b50e16b9 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -18,9 +18,17 @@ import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.config.BlockNodeContextFactory; +import com.hedera.block.server.data.ObjectEvent; +import com.hedera.block.server.mediator.StreamMediator; +import com.hedera.block.server.persistence.storage.read.BlockReader; +import com.hedera.hapi.block.SubscribeStreamResponse; +import com.hedera.hapi.block.stream.Block; +import com.hedera.hapi.block.stream.BlockItem; import dagger.Binds; import dagger.Module; import dagger.Provides; +import edu.umd.cs.findbugs.annotations.NonNull; +import io.helidon.webserver.WebServerConfig; import java.io.IOException; import javax.inject.Singleton; @@ -46,8 +54,8 @@ public interface BlockNodeAppInjectionModule { * * @return a block node context singleton */ - @Provides @Singleton + @Provides static BlockNodeContext provideBlockNodeContext() { try { return BlockNodeContextFactory.create(); @@ -55,4 +63,22 @@ static BlockNodeContext provideBlockNodeContext() { throw new RuntimeException(e); } } + + @Singleton + @Provides + static BlockStreamService provideBlockStreamService( + @NonNull + final StreamMediator> + streamMediator, + @NonNull final BlockReader blockReader, + @NonNull final ServiceStatus serviceStatus, + @NonNull final BlockNodeContext blockNodeContext) { + return new BlockStreamService(streamMediator, blockReader, serviceStatus, blockNodeContext); + } + + @Singleton + @Provides + static WebServerConfig.Builder provideWebServerConfigBuilder() { + return WebServerConfig.builder(); + } } diff --git a/server/src/main/java/com/hedera/block/server/BlockStreamService.java b/server/src/main/java/com/hedera/block/server/BlockStreamService.java index 3b820b09..4ab2654e 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -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 @@ -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> diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java new file mode 100644 index 00000000..6c1016bc --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.config; + +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.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 dagger.Module; +import dagger.Provides; +import edu.umd.cs.findbugs.annotations.NonNull; +import java.io.IOException; +import java.nio.file.Path; +import javax.inject.Singleton; + +@Module +public interface ConfigInjectionModule { + + static final String APPLICATION_PROPERTIES = "app.properties"; + + @Singleton + @Provides + static Configuration provideConfiguration() { + try { + return ConfigurationBuilder.create() + .withSource(SystemEnvironmentConfigSource.getInstance()) + .withSource(SystemPropertiesConfigSource.getInstance()) + .withSource(new ClasspathFileConfigSource(Path.of(APPLICATION_PROPERTIES))) + .autoDiscoverExtensions() + .build(); + } catch (IOException e) { + throw new RuntimeException("Failed to create configuration", e); + } + } + + @Singleton + @Provides + static PersistenceStorageConfig providePersistenceStorageConfig( + @NonNull Configuration configuration) { + return configuration.getConfigData(PersistenceStorageConfig.class); + } + + @Singleton + @Provides + static MetricsConfig provideMetricsConfig(@NonNull Configuration configuration) { + return configuration.getConfigData(MetricsConfig.class); + } + + @Singleton + @Provides + static PrometheusConfig providePrometheusConfig(@NonNull Configuration configuration) { + return configuration.getConfigData(PrometheusConfig.class); + } + + @Singleton + @Provides + static ConsumerConfig provideConsumerConfig(@NonNull Configuration configuration) { + return configuration.getConfigData(ConsumerConfig.class); + } + + @Singleton + @Provides + static BasicCommonConfig provideBasicCommonConfig(@NonNull Configuration configuration) { + return configuration.getConfigData(BasicCommonConfig.class); + } +} diff --git a/server/src/main/java/com/hedera/block/server/mediator/MediatorInjectionModule.java b/server/src/main/java/com/hedera/block/server/mediator/MediatorInjectionModule.java new file mode 100644 index 00000000..f50e107b --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/mediator/MediatorInjectionModule.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.mediator; + +import com.hedera.block.server.ServiceStatus; +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.data.ObjectEvent; +import com.hedera.block.server.persistence.storage.write.BlockWriter; +import com.hedera.hapi.block.SubscribeStreamResponse; +import com.hedera.hapi.block.stream.BlockItem; +import dagger.Module; +import dagger.Provides; +import edu.umd.cs.findbugs.annotations.NonNull; +import javax.inject.Singleton; + +/** A Dagger module for providing dependencies for Mediator Module.` */ +@Module +public interface MediatorInjectionModule { + + /** + * Provides the stream mediator. + * + * @param blockWriter the block writer + * @param blockNodeContext the block node context + * @param serviceStatus the service status + * @return the stream mediator + */ + @Provides + @Singleton + static StreamMediator> providesStreamMediator( + @NonNull BlockWriter blockWriter, + @NonNull BlockNodeContext blockNodeContext, + @NonNull ServiceStatus serviceStatus) { + return LiveStreamMediatorBuilder.newBuilder(blockWriter, blockNodeContext, serviceStatus) + .build(); + } +} diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java index 5b3a940b..4669f93b 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java @@ -17,8 +17,11 @@ package com.hedera.block.server.persistence.storage; import com.hedera.block.server.config.BlockNodeContext; +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.stream.Block; import com.hedera.hapi.block.stream.BlockItem; import dagger.Module; import dagger.Provides; @@ -45,4 +48,10 @@ static BlockWriter providesBlockWriter(@NonNull BlockNodeContext bloc throw new RuntimeException("Failed to create block writer", e); } } + + @Provides + @Singleton + static BlockReader providesBlockReader(@NonNull PersistenceStorageConfig config) { + return BlockAsDirReaderBuilder.newBuilder(config).build(); + } } diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java new file mode 100644 index 00000000..92f7f480 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.hedera.block.server.health.HealthService; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.WebServerConfig; +import io.helidon.webserver.grpc.GrpcRouting; +import io.helidon.webserver.http.HttpRouting; +import java.io.IOException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class BlockNodeAppTest { + + @Mock private ServiceStatus serviceStatus; + + @Mock private HealthService healthService; + + @Mock private BlockStreamService blockStreamService; + + @Mock private WebServerConfig.Builder webServerBuilder; + + @Mock private WebServer webServer; + + @InjectMocks private BlockNodeApp blockNodeApp; + + @BeforeEach + void setup() { + when(webServerBuilder.port(8080)).thenReturn(webServerBuilder); + when(webServerBuilder.addRouting(any(GrpcRouting.Builder.class))) + .thenReturn(webServerBuilder); + when(webServerBuilder.addRouting(any(HttpRouting.Builder.class))) + .thenReturn(webServerBuilder); + when(webServerBuilder.build()).thenReturn(webServer); + when(healthService.getHealthRootPath()).thenReturn("/health"); + } + + @Test + void testStartServer() throws IOException { + // Act + blockNodeApp.start(); + + // Assert + verify(serviceStatus).setWebServer(webServer); + verify(webServer).start(); + verify(healthService).getHealthRootPath(); + verify(webServerBuilder).port(8080); + verify(webServerBuilder).addRouting(any(GrpcRouting.Builder.class)); + verify(webServerBuilder).addRouting(any(HttpRouting.Builder.class)); + verify(webServerBuilder).build(); + } +} From e945fb10558cff1285b5ae5b2c09fdc8646588a4 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 15:34:13 -0600 Subject: [PATCH 03/17] Improving test and including missing java docs Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/BlockNodeApp.java | 8 ++-- .../server/BlockNodeAppInjectionModule.java | 14 ++++++ .../server/config/ConfigInjectionModule.java | 43 ++++++++++++++++++- .../storage/PersistenceInjectionModule.java | 6 +++ .../hedera/block/server/BlockNodeAppTest.java | 2 - 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java index 5b0b8a9f..8bbcad0a 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java @@ -44,10 +44,12 @@ public class BlockNodeApp { 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 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( diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index b50e16b9..a0049ce3 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -64,6 +64,15 @@ static BlockNodeContext provideBlockNodeContext() { } } + /** + * Provides a block stream service singleton using DI. + * + * @param streamMediator should come from DI + * @param blockReader should come from DI + * @param serviceStatus should come from DI + * @param blockNodeContext should come from DI + * @return a block stream service singleton + */ @Singleton @Provides static BlockStreamService provideBlockStreamService( @@ -76,6 +85,11 @@ static BlockStreamService provideBlockStreamService( return new BlockStreamService(streamMediator, blockReader, serviceStatus, blockNodeContext); } + /** + * Provides a web server config builder singleton using DI. + * + * @return a web server config builder singleton + */ @Singleton @Provides static WebServerConfig.Builder provideWebServerConfigBuilder() { diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java index 6c1016bc..4b60e043 100644 --- a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -33,11 +33,22 @@ import java.nio.file.Path; import javax.inject.Singleton; +/** + * A Dagger module for providing configuration dependencies, any specific configuration should be + * part of this module. + */ @Module public interface ConfigInjectionModule { - static final String APPLICATION_PROPERTIES = "app.properties"; + /** The application properties file name within the resources package. */ + String APPLICATION_PROPERTIES = "app.properties"; + /** + * Provides a configuration singleton using the configuration builder. Injected by the DI + * Framework. + * + * @return a configuration singleton + */ @Singleton @Provides static Configuration provideConfiguration() { @@ -53,6 +64,12 @@ static Configuration provideConfiguration() { } } + /** + * Provides a persistence storage configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a persistence storage configuration singleton + */ @Singleton @Provides static PersistenceStorageConfig providePersistenceStorageConfig( @@ -60,24 +77,48 @@ static PersistenceStorageConfig providePersistenceStorageConfig( return configuration.getConfigData(PersistenceStorageConfig.class); } + /** + * Provides a metrics configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a metrics configuration singleton + */ @Singleton @Provides static MetricsConfig provideMetricsConfig(@NonNull Configuration configuration) { return configuration.getConfigData(MetricsConfig.class); } + /** + * Provides a Prometheus configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a Prometheus configuration singleton + */ @Singleton @Provides static PrometheusConfig providePrometheusConfig(@NonNull Configuration configuration) { return configuration.getConfigData(PrometheusConfig.class); } + /** + * Provides a consumer configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a consumer configuration singleton + */ @Singleton @Provides static ConsumerConfig provideConsumerConfig(@NonNull Configuration configuration) { return configuration.getConfigData(ConsumerConfig.class); } + /** + * Provides a basic common configuration singleton using the configuration. + * + * @param configuration is the configuration singleton + * @return a basic common configuration singleton + */ @Singleton @Provides static BasicCommonConfig provideBasicCommonConfig(@NonNull Configuration configuration) { diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java index 4669f93b..eabe3285 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java @@ -49,6 +49,12 @@ static BlockWriter providesBlockWriter(@NonNull BlockNodeContext bloc } } + /** + * Provides a block reader singleton using the persistence storage config. + * + * @param config the persistence storage configuration needed to build the block reader + * @return a block reader singleton + */ @Provides @Singleton static BlockReader providesBlockReader(@NonNull PersistenceStorageConfig config) { diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java index 92f7f480..f989f4c4 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java @@ -40,8 +40,6 @@ class BlockNodeAppTest { @Mock private HealthService healthService; - @Mock private BlockStreamService blockStreamService; - @Mock private WebServerConfig.Builder webServerBuilder; @Mock private WebServer webServer; From 58b61a797a73e07a0e759d9da4a60b227dafaed2 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 15:42:09 -0600 Subject: [PATCH 04/17] bringing back mock needed for test Signed-off-by: Alfredo Gutierrez --- .../src/test/java/com/hedera/block/server/BlockNodeAppTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java index f989f4c4..92f7f480 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppTest.java @@ -40,6 +40,8 @@ class BlockNodeAppTest { @Mock private HealthService healthService; + @Mock private BlockStreamService blockStreamService; + @Mock private WebServerConfig.Builder webServerBuilder; @Mock private WebServer webServer; From 41db6caa11f61c9b084ec7fa07b23f76c919a0e1 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 16:13:10 -0600 Subject: [PATCH 05/17] started refactor of BlockNodeContextFactory and BlockNodeContext, is working, some tests are failing, but saving this checkpoint before further large scale refactor. Signed-off-by: Alfredo Gutierrez --- .../BlockNodeAppInjectionComponent.java | 4 +- .../server/BlockNodeAppInjectionModule.java | 13 ++-- .../config/BlockNodeContextFactory.java | 65 ++----------------- .../metrics/MetricsInjectionModule.java | 43 ++++++++++++ 4 files changed, 56 insertions(+), 69 deletions(-) create mode 100644 server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index 8f8e91a4..1c358ff7 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -19,6 +19,7 @@ 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.storage.PersistenceInjectionModule; import dagger.Component; import javax.inject.Singleton; @@ -31,7 +32,8 @@ HealthInjectionModule.class, PersistenceInjectionModule.class, MediatorInjectionModule.class, - ConfigInjectionModule.class + ConfigInjectionModule.class, + MetricsInjectionModule.class, }) public interface BlockNodeAppInjectionComponent { /** diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index a0049ce3..8d8c3832 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -20,16 +20,18 @@ import com.hedera.block.server.config.BlockNodeContextFactory; import com.hedera.block.server.data.ObjectEvent; import com.hedera.block.server.mediator.StreamMediator; +import com.hedera.block.server.metrics.MetricsService; import com.hedera.block.server.persistence.storage.read.BlockReader; import com.hedera.hapi.block.SubscribeStreamResponse; import com.hedera.hapi.block.stream.Block; import com.hedera.hapi.block.stream.BlockItem; +import com.swirlds.config.api.Configuration; +import com.swirlds.metrics.api.Metrics; import dagger.Binds; import dagger.Module; import dagger.Provides; import edu.umd.cs.findbugs.annotations.NonNull; import io.helidon.webserver.WebServerConfig; -import java.io.IOException; import javax.inject.Singleton; /** @@ -56,12 +58,9 @@ public interface BlockNodeAppInjectionModule { */ @Singleton @Provides - static BlockNodeContext provideBlockNodeContext() { - try { - return BlockNodeContextFactory.create(); - } catch (IOException e) { - throw new RuntimeException(e); - } + static BlockNodeContext provideBlockNodeContext( + Configuration config, Metrics metrics, MetricsService metricsService) { + return BlockNodeContextFactory.create(config, metrics, metricsService); } /** diff --git a/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java b/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java index 9081b770..aac7b505 100644 --- a/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java +++ b/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java @@ -17,75 +17,18 @@ package com.hedera.block.server.config; import com.hedera.block.server.metrics.MetricsService; -import com.swirlds.common.metrics.platform.DefaultMetricsProvider; 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 com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.IOException; -import java.nio.file.Path; -/** - * Use the static method create() to obtain a new {@link BlockNodeContext} when initializing the - * application. - * - *

When a context is created all enabled sources of configuration information will be read and - * applicable values made available through the context created.
- * The application should use the context to obtain configuration and metrics support. - */ +/** Deprecated. */ public class BlockNodeContextFactory { - /** - * A resource file name from which application configuration is read. The properties in this - * file are available as configuration from the {@link BlockNodeContext}. - */ - private static final String APPLICATION_PROPERTIES = "app.properties"; - private BlockNodeContextFactory() {} - /** - * Create a new application context for use in the system. The context is needed at - * initialization. - * - * @return a context with configuration and metrics. - * @throws IOException when the java libraries fail to read information from a configuration - * source. - */ - @NonNull - public static BlockNodeContext create() throws IOException { - final Configuration configuration = getConfiguration(); - final Metrics metrics = getMetrics(configuration); - final MetricsService metricsService = new MetricsService(metrics); - return new BlockNodeContext(metrics, metricsService, configuration); - } - - /** - * Read configuration for this system. The configuration sources will include environment - * variables, system properties, and the properties file named {@value APPLICATION_PROPERTIES}. - * - * @return the configuration as read from environment, properties, and files. - * @throws IOException when the java libraries fail to read information from a configuration - * source. - */ - @NonNull - private static Configuration getConfiguration() throws IOException { - - return ConfigurationBuilder.create() - .withSource(SystemEnvironmentConfigSource.getInstance()) - .withSource(SystemPropertiesConfigSource.getInstance()) - .withSource(new ClasspathFileConfigSource(Path.of(APPLICATION_PROPERTIES))) - .autoDiscoverExtensions() - .build(); - } - @NonNull - private static Metrics getMetrics(@NonNull final Configuration configuration) { - final DefaultMetricsProvider metricsProvider = new DefaultMetricsProvider(configuration); - final Metrics metrics = metricsProvider.createGlobalMetrics(); - metricsProvider.start(); - return metrics; + public static BlockNodeContext create( + Configuration config, Metrics metrics, MetricsService metricsService) { + return new BlockNodeContext(metrics, metricsService, config); } } diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java new file mode 100644 index 00000000..cf4af8e4 --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.metrics; + +import com.swirlds.common.metrics.platform.DefaultMetricsProvider; +import com.swirlds.config.api.Configuration; +import com.swirlds.metrics.api.Metrics; +import dagger.Module; +import dagger.Provides; +import javax.inject.Singleton; + +@Module +public interface MetricsInjectionModule { + + @Singleton + @Provides + static MetricsService provideMetricsService(Metrics metrics) { + return new MetricsService(metrics); + } + + @Singleton + @Provides + static Metrics provideMetrics(Configuration configuration) { + final DefaultMetricsProvider metricsProvider = new DefaultMetricsProvider(configuration); + final Metrics metrics = metricsProvider.createGlobalMetrics(); + metricsProvider.start(); + return metrics; + } +} From 3f563f335bd7be21bda02bcf35fdf5db6ade8321 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 18:09:48 -0600 Subject: [PATCH 06/17] Fixed UT for existing tests, ContextFactory is just a Shell, we should be able to get rid of it soon. Signed-off-by: Alfredo Gutierrez --- .../BlockNodeAppInjectionModuleTest.java | 6 +++-- .../config/BlockNodeContextFactoryTest.java | 16 ++++++++++--- .../mediator/LiveStreamMediatorImplTest.java | 17 +++++++------ .../ProducerBlockItemObserverTest.java | 3 +-- .../block/server/util/TestConfigUtil.java | 24 ++++++++++++------- 5 files changed, 42 insertions(+), 24 deletions(-) diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java index 704409c6..6281e162 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java @@ -17,13 +17,15 @@ package com.hedera.block.server; import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.util.TestConfigUtil; +import java.io.IOException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class BlockNodeAppInjectionModuleTest { @Test - void testProvideBlockNodeContext() { - BlockNodeContext blockNodeContext = BlockNodeAppInjectionModule.provideBlockNodeContext(); + void testProvideBlockNodeContext() throws IOException { + BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); Assertions.assertNotNull(blockNodeContext); Assertions.assertNotNull(blockNodeContext.configuration()); diff --git a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java index cd02cd8b..8c690247 100644 --- a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java +++ b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java @@ -18,16 +18,26 @@ import static org.junit.jupiter.api.Assertions.*; +import com.hedera.block.server.util.TestConfigUtil; import java.io.IOException; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; class BlockNodeContextFactoryTest { @Test void create_returnsBlockNodeContext() throws IOException { - BlockNodeContext context = BlockNodeContextFactory.create(); - assertNotNull(context.metrics()); - assertNotNull(context.configuration()); + BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); + + BlockNodeContext context = + BlockNodeContextFactory.create( + blockNodeContext.configuration(), + blockNodeContext.metrics(), + blockNodeContext.metricsService()); + + Assertions.assertEquals(context.configuration(), blockNodeContext.configuration()); + Assertions.assertEquals(context.metrics(), blockNodeContext.metrics()); + Assertions.assertEquals(context.metricsService(), blockNodeContext.metricsService()); } } diff --git a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java index 6fcffe6b..42f703ce 100644 --- a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java +++ b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java @@ -30,7 +30,6 @@ import com.hedera.block.server.ServiceStatusImpl; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.config.BlockNodeContextFactory; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.consumer.ConsumerStreamResponseObserver; import com.hedera.block.server.data.ObjectEvent; @@ -95,7 +94,7 @@ public LiveStreamMediatorImplTest() throws IOException { @Test public void testUnsubscribeEach() throws InterruptedException, IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediatorBuilder = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()); @@ -140,7 +139,7 @@ public void testUnsubscribeEach() throws InterruptedException, IOException { @Test public void testMediatorPersistenceWithoutSubscribers() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -161,7 +160,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testMediatorPublishEventToSubscribers() throws IOException, InterruptedException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -221,7 +220,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testSubAndUnsubHandling() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -257,7 +256,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testOnCancelSubscriptionHandling() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -292,7 +291,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testOnCloseSubscriptionHandling() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -327,7 +326,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testMediatorBlocksPublishAfterException() throws IOException, InterruptedException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) @@ -362,7 +361,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) @Test public void testUnsubscribeWhenNotSubscribed() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) diff --git a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java index 774a3c6b..15afd780 100644 --- a/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java +++ b/server/src/test/java/com/hedera/block/server/producer/ProducerBlockItemObserverTest.java @@ -32,7 +32,6 @@ import com.hedera.block.server.ServiceStatus; import com.hedera.block.server.ServiceStatusImpl; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.config.BlockNodeContextFactory; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.consumer.ConsumerStreamResponseObserver; import com.hedera.block.server.data.ObjectEvent; @@ -118,7 +117,7 @@ public void testProducerOnNext() throws IOException, NoSuchAlgorithmException { @Test public void testProducerWithManyConsumers() throws IOException { - final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); + final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( blockWriter, blockNodeContext, new ServiceStatusImpl()) diff --git a/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java b/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java index 30f3e121..5519e7f4 100644 --- a/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java +++ b/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java @@ -17,11 +17,13 @@ package com.hedera.block.server.util; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.config.BlockNodeContextFactory; import com.hedera.block.server.config.TestConfigBuilder; import com.hedera.block.server.consumer.ConsumerConfig; +import com.hedera.block.server.metrics.MetricsService; +import com.swirlds.common.metrics.platform.DefaultMetricsProvider; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.sources.ClasspathFileConfigSource; +import com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.nio.file.Path; @@ -40,11 +42,6 @@ private TestConfigUtil() {} public static BlockNodeContext getTestBlockNodeContext( @NonNull Map customProperties) throws IOException { - // we still use the BlockNodeContextFactory to create the BlockNodeContext temporally, - // but we will replace the configuration with a test configuration - // sooner we will need to create a metrics mock, and never use the BlockNodeContextFactory. - BlockNodeContext blockNodeContext = BlockNodeContextFactory.create(); - // create test configuration TestConfigBuilder testConfigBuilder = new TestConfigBuilder(true) @@ -61,11 +58,22 @@ public static BlockNodeContext getTestBlockNodeContext( Configuration testConfiguration = testConfigBuilder.getOrCreateConfig(); - return new BlockNodeContext( - blockNodeContext.metrics(), blockNodeContext.metricsService(), testConfiguration); + Metrics metrics = getTestMetrics(testConfiguration); + + MetricsService metricsService = new MetricsService(metrics); + + return new BlockNodeContext(metrics, metricsService, testConfiguration); } public static BlockNodeContext getTestBlockNodeContext() throws IOException { return getTestBlockNodeContext(Collections.emptyMap()); } + + // TODO: we need to create a Mock metrics, and avoid using the real metrics for tests + public static Metrics getTestMetrics(@NonNull Configuration configuration) { + final DefaultMetricsProvider metricsProvider = new DefaultMetricsProvider(configuration); + final Metrics metrics = metricsProvider.createGlobalMetrics(); + metricsProvider.start(); + return metrics; + } } From a00e0b397a9fd5b0bf128178231d42a23434c13b Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 18:10:58 -0600 Subject: [PATCH 07/17] fixing warnings Signed-off-by: Alfredo Gutierrez --- .../block/server/config/BlockNodeContextFactoryTest.java | 2 -- .../block/server/mediator/LiveStreamMediatorImplTest.java | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java index 8c690247..70a0e79d 100644 --- a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java +++ b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java @@ -16,8 +16,6 @@ package com.hedera.block.server.config; -import static org.junit.jupiter.api.Assertions.*; - import com.hedera.block.server.util.TestConfigUtil; import java.io.IOException; import org.junit.jupiter.api.Assertions; diff --git a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java index 42f703ce..f0f6ab21 100644 --- a/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java +++ b/server/src/test/java/com/hedera/block/server/mediator/LiveStreamMediatorImplTest.java @@ -30,7 +30,6 @@ import com.hedera.block.server.ServiceStatusImpl; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.consumer.ConsumerStreamResponseObserver; import com.hedera.block.server.data.ObjectEvent; import com.hedera.block.server.persistence.storage.write.BlockWriter; @@ -80,7 +79,6 @@ public class LiveStreamMediatorImplTest { private static final int testTimeout = 200; - private final ConsumerConfig consumerConfig = new ConsumerConfig(TIMEOUT_THRESHOLD_MILLIS); private final BlockNodeContext testContext; public LiveStreamMediatorImplTest() throws IOException { @@ -158,7 +156,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) } @Test - public void testMediatorPublishEventToSubscribers() throws IOException, InterruptedException { + public void testMediatorPublishEventToSubscribers() throws IOException { final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = @@ -325,7 +323,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) } @Test - public void testMediatorBlocksPublishAfterException() throws IOException, InterruptedException { + public void testMediatorBlocksPublishAfterException() throws IOException { final BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); final var streamMediator = LiveStreamMediatorBuilder.newBuilder( From f9b69e2625344805baa1995eef0cba2a76641d40 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 18:22:59 -0600 Subject: [PATCH 08/17] Got rid of the BlockNodeContextFactory, next step, probably for a future PR, is to get Rid of the BlockNodeContext completely. Now that we have Dagger dependencies are cheap, and is better to inject the minimum amount of them, only when in need. Signed-off-by: Alfredo Gutierrez --- .../server/BlockNodeAppInjectionModule.java | 8 ++-- .../block/server/config/BlockNodeContext.java | 6 +-- .../config/BlockNodeContextFactory.java | 34 --------------- .../BlockNodeAppInjectionModuleTest.java | 1 - .../config/BlockNodeContextFactoryTest.java | 41 ------------------- .../server/config/BlockNodeContextTest.java | 5 +-- .../block/server/util/TestConfigUtil.java | 2 +- 7 files changed, 6 insertions(+), 91 deletions(-) delete mode 100644 server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java delete mode 100644 server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index 8d8c3832..73f72334 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -17,7 +17,6 @@ package com.hedera.block.server; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.config.BlockNodeContextFactory; import com.hedera.block.server.data.ObjectEvent; import com.hedera.block.server.mediator.StreamMediator; import com.hedera.block.server.metrics.MetricsService; @@ -26,7 +25,6 @@ import com.hedera.hapi.block.stream.Block; import com.hedera.hapi.block.stream.BlockItem; import com.swirlds.config.api.Configuration; -import com.swirlds.metrics.api.Metrics; import dagger.Binds; import dagger.Module; import dagger.Provides; @@ -52,15 +50,15 @@ public interface BlockNodeAppInjectionModule { ServiceStatus bindServiceStatus(ServiceStatusImpl serviceStatus); /** - * Provides a block node context singleton using the factory. + * Provides a block node context singleton. * * @return a block node context singleton */ @Singleton @Provides static BlockNodeContext provideBlockNodeContext( - Configuration config, Metrics metrics, MetricsService metricsService) { - return BlockNodeContextFactory.create(config, metrics, metricsService); + Configuration config, MetricsService metricsService) { + return new BlockNodeContext(metricsService, config); } /** diff --git a/server/src/main/java/com/hedera/block/server/config/BlockNodeContext.java b/server/src/main/java/com/hedera/block/server/config/BlockNodeContext.java index 92fc36d3..3d3fa452 100644 --- a/server/src/main/java/com/hedera/block/server/config/BlockNodeContext.java +++ b/server/src/main/java/com/hedera/block/server/config/BlockNodeContext.java @@ -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) {} diff --git a/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java b/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java deleted file mode 100644 index aac7b505..00000000 --- a/server/src/main/java/com/hedera/block/server/config/BlockNodeContextFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.block.server.config; - -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; - -/** Deprecated. */ -public class BlockNodeContextFactory { - - private BlockNodeContextFactory() {} - - @NonNull - public static BlockNodeContext create( - Configuration config, Metrics metrics, MetricsService metricsService) { - return new BlockNodeContext(metrics, metricsService, config); - } -} diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java index 6281e162..27cabfc4 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java @@ -29,7 +29,6 @@ void testProvideBlockNodeContext() throws IOException { Assertions.assertNotNull(blockNodeContext); Assertions.assertNotNull(blockNodeContext.configuration()); - Assertions.assertNotNull(blockNodeContext.metrics()); Assertions.assertNotNull(blockNodeContext.metricsService()); } } diff --git a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java deleted file mode 100644 index 70a0e79d..00000000 --- a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextFactoryTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2024 Hedera Hashgraph, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hedera.block.server.config; - -import com.hedera.block.server.util.TestConfigUtil; -import java.io.IOException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -class BlockNodeContextFactoryTest { - - @Test - void create_returnsBlockNodeContext() throws IOException { - - BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); - - BlockNodeContext context = - BlockNodeContextFactory.create( - blockNodeContext.configuration(), - blockNodeContext.metrics(), - blockNodeContext.metricsService()); - - Assertions.assertEquals(context.configuration(), blockNodeContext.configuration()); - Assertions.assertEquals(context.metrics(), blockNodeContext.metrics()); - Assertions.assertEquals(context.metricsService(), blockNodeContext.metricsService()); - } -} diff --git a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextTest.java b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextTest.java index 690fc450..ef257300 100644 --- a/server/src/test/java/com/hedera/block/server/config/BlockNodeContextTest.java +++ b/server/src/test/java/com/hedera/block/server/config/BlockNodeContextTest.java @@ -21,20 +21,17 @@ import com.hedera.block.server.metrics.MetricsService; import com.swirlds.config.api.Configuration; -import com.swirlds.metrics.api.Metrics; import org.junit.jupiter.api.Test; class BlockNodeContextTest { @Test void BlockNodeContext_initializesWithMetricsAndConfiguration() { - Metrics metrics = mock(Metrics.class); Configuration configuration = mock(Configuration.class); MetricsService metricsService = mock(MetricsService.class); - BlockNodeContext context = new BlockNodeContext(metrics, metricsService, configuration); + BlockNodeContext context = new BlockNodeContext(metricsService, configuration); - assertEquals(metrics, context.metrics()); assertEquals(metricsService, context.metricsService()); assertEquals(configuration, context.configuration()); } diff --git a/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java b/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java index 5519e7f4..ef3789dc 100644 --- a/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java +++ b/server/src/test/java/com/hedera/block/server/util/TestConfigUtil.java @@ -62,7 +62,7 @@ public static BlockNodeContext getTestBlockNodeContext( MetricsService metricsService = new MetricsService(metrics); - return new BlockNodeContext(metrics, metricsService, testConfiguration); + return new BlockNodeContext(metricsService, testConfiguration); } public static BlockNodeContext getTestBlockNodeContext() throws IOException { From 883969ceba8fb29e740bccd996ab35d40438d973 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 18:29:22 -0600 Subject: [PATCH 09/17] fixed javadocs and exported metrics to remove warning Signed-off-by: Alfredo Gutierrez --- .../block/server/BlockNodeAppInjectionModule.java | 2 ++ .../server/metrics/MetricsInjectionModule.java | 13 +++++++++++++ server/src/main/java/module-info.java | 1 + 3 files changed, 16 insertions(+) diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index 73f72334..ddfa8692 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -52,6 +52,8 @@ public interface BlockNodeAppInjectionModule { /** * 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 diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java index cf4af8e4..f65d3e8e 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsInjectionModule.java @@ -23,15 +23,28 @@ import dagger.Provides; import javax.inject.Singleton; +/** The module used to inject the metrics service and metrics into the application. */ @Module public interface MetricsInjectionModule { + /** + * Provides the metrics service. + * + * @param metrics the metrics to be used by the service + * @return the metrics service + */ @Singleton @Provides static MetricsService provideMetricsService(Metrics metrics) { return new MetricsService(metrics); } + /** + * Provides the metrics. + * + * @param configuration the configuration to be used by the metrics + * @return the metrics + */ @Singleton @Provides static Metrics provideMetrics(Configuration configuration) { diff --git a/server/src/main/java/module-info.java b/server/src/main/java/module-info.java index 4ad339a6..b19703f2 100644 --- a/server/src/main/java/module-info.java +++ b/server/src/main/java/module-info.java @@ -10,6 +10,7 @@ exports com.hedera.block.server.persistence.storage.remove; exports com.hedera.block.server.config; exports com.hedera.block.server.mediator; + exports com.hedera.block.server.metrics; exports com.hedera.block.server.data; exports com.hedera.block.server.health; From 30cda24db9c119daca943cdee8c7d5244ce87bca Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 19:20:45 -0600 Subject: [PATCH 10/17] Refactor BlockNodeAppInjectionComponent to need an external configuration instead of providing one itself. Signed-off-by: Alfredo Gutierrez --- .../BlockNodeAppInjectionComponent.java | 28 +++++++++++++++++ .../java/com/hedera/block/server/Server.java | 25 +++++++++++++++- .../server/config/ConfigInjectionModule.java | 30 ------------------- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index 1c358ff7..49f6863e 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -21,6 +21,8 @@ import com.hedera.block.server.mediator.MediatorInjectionModule; import com.hedera.block.server.metrics.MetricsInjectionModule; import com.hedera.block.server.persistence.storage.PersistenceInjectionModule; +import com.swirlds.config.api.Configuration; +import dagger.BindsInstance; import dagger.Component; import javax.inject.Singleton; @@ -42,4 +44,30 @@ public interface BlockNodeAppInjectionComponent { * @return the block node app server */ BlockNodeApp getBlockNodeApp(); + + // @Component.Factory + // interface Factory { + // BlockNodeAppInjectionComponent create(@BindsInstance Configuration configuration); + // } + + /** Builder for the BlockNodeAppInjectionComponent. */ + @Component.Builder + interface Builder { + + /** + * Bind the configuration to the BlockNodeAppInjectionComponent. + * + * @param configuration the configuration + * @return the BlockNodeAppInjectionComponentBuilder + */ + @BindsInstance + Builder configuration(Configuration configuration); + + /** + * Build the BlockNodeAppInjectionComponent. + * + * @return the BlockNodeAppInjectionComponent + */ + BlockNodeAppInjectionComponent build(); + } } diff --git a/server/src/main/java/com/hedera/block/server/Server.java b/server/src/main/java/com/hedera/block/server/Server.java index 77d5e68c..4c8b0413 100644 --- a/server/src/main/java/com/hedera/block/server/Server.java +++ b/server/src/main/java/com/hedera/block/server/Server.java @@ -19,12 +19,19 @@ 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 { private static final Logger LOGGER = System.getLogger(Server.class.getName()); + private static final String APPLICATION_PROPERTIES = "app.properties"; private Server() {} @@ -36,8 +43,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(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.factory().create(configuration); final BlockNodeAppInjectionComponent daggerComponent = - DaggerBlockNodeAppInjectionComponent.create(); + DaggerBlockNodeAppInjectionComponent.builder().configuration(configuration).build(); + + // Use Dagger DI Component to start the BlockNodeApp with all wired dependencies final BlockNodeApp blockNodeApp = daggerComponent.getBlockNodeApp(); blockNodeApp.start(); } diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java index 4b60e043..3e0ae7cf 100644 --- a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -22,15 +22,9 @@ import com.swirlds.common.metrics.config.MetricsConfig; import com.swirlds.common.metrics.platform.prometheus.PrometheusConfig; 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 dagger.Module; import dagger.Provides; import edu.umd.cs.findbugs.annotations.NonNull; -import java.io.IOException; -import java.nio.file.Path; import javax.inject.Singleton; /** @@ -40,30 +34,6 @@ @Module public interface ConfigInjectionModule { - /** The application properties file name within the resources package. */ - String APPLICATION_PROPERTIES = "app.properties"; - - /** - * Provides a configuration singleton using the configuration builder. Injected by the DI - * Framework. - * - * @return a configuration singleton - */ - @Singleton - @Provides - static Configuration provideConfiguration() { - try { - return ConfigurationBuilder.create() - .withSource(SystemEnvironmentConfigSource.getInstance()) - .withSource(SystemPropertiesConfigSource.getInstance()) - .withSource(new ClasspathFileConfigSource(Path.of(APPLICATION_PROPERTIES))) - .autoDiscoverExtensions() - .build(); - } catch (IOException e) { - throw new RuntimeException("Failed to create configuration", e); - } - } - /** * Provides a persistence storage configuration singleton using the configuration. * From 99aa01fa4c90ed43c294328704f4b46cbec2720e Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 20:51:04 -0600 Subject: [PATCH 11/17] Moved PersistenceInjectionModule to persistance package instead of persistence.storage Added export metricsService to the module-info Refactored Dagger Component to receive a Configuration from outside. Added UT for MediatorInjectionModule Signed-off-by: Alfredo Gutierrez --- .../BlockNodeAppInjectionComponent.java | 2 +- .../PersistenceInjectionModule.java | 3 +- server/src/main/java/module-info.java | 1 + .../mediator/MediatorInjectionModuleTest.java | 57 +++++++++++++++++++ .../PersistenceInjectionModuleTest.java | 21 +++++++ 5 files changed, 82 insertions(+), 2 deletions(-) rename server/src/main/java/com/hedera/block/server/persistence/{storage => }/PersistenceInjectionModule.java (94%) create mode 100644 server/src/test/java/com/hedera/block/server/mediator/MediatorInjectionModuleTest.java create mode 100644 server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index 49f6863e..05ed8be9 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -20,7 +20,7 @@ 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.storage.PersistenceInjectionModule; +import com.hedera.block.server.persistence.PersistenceInjectionModule; import com.swirlds.config.api.Configuration; import dagger.BindsInstance; import dagger.Component; diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java b/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java similarity index 94% rename from server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java rename to server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java index eabe3285..e9337b18 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/PersistenceInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.hedera.block.server.persistence.storage; +package com.hedera.block.server.persistence; import com.hedera.block.server.config.BlockNodeContext; +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; diff --git a/server/src/main/java/module-info.java b/server/src/main/java/module-info.java index b19703f2..4a938f30 100644 --- a/server/src/main/java/module-info.java +++ b/server/src/main/java/module-info.java @@ -13,6 +13,7 @@ exports com.hedera.block.server.metrics; exports com.hedera.block.server.data; exports com.hedera.block.server.health; + exports com.hedera.block.server.persistence; requires com.hedera.block.stream; requires com.google.protobuf; diff --git a/server/src/test/java/com/hedera/block/server/mediator/MediatorInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/mediator/MediatorInjectionModuleTest.java new file mode 100644 index 00000000..2a05d499 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/mediator/MediatorInjectionModuleTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.mediator; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import com.hedera.block.server.ServiceStatus; +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.data.ObjectEvent; +import com.hedera.block.server.persistence.storage.write.BlockWriter; +import com.hedera.hapi.block.SubscribeStreamResponse; +import com.hedera.hapi.block.stream.BlockItem; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class MediatorInjectionModuleTest { + + @Mock private BlockWriter blockWriter; + + @Mock private BlockNodeContext blockNodeContext; + + @Mock private ServiceStatus serviceStatus; + + @BeforeEach + void setup() { + // Any setup before each test can be done here + } + + @Test + void testProvidesStreamMediator() { + // Call the method under test + StreamMediator> streamMediator = + MediatorInjectionModule.providesStreamMediator( + blockWriter, blockNodeContext, serviceStatus); + + // Verify that the streamMediator is correctly instantiated + assertNotNull(streamMediator); + } +} diff --git a/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java new file mode 100644 index 00000000..49596d20 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.persistence; + +import static org.junit.jupiter.api.Assertions.*; + +class PersistenceInjectionModuleTest {} From 1b2690c66371cf71b055feb98bbb8145e2ebca95 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 20:55:39 -0600 Subject: [PATCH 12/17] Added UT for PersistenceInjectionModule Signed-off-by: Alfredo Gutierrez --- .../PersistenceInjectionModuleTest.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java index 49596d20..76641b76 100644 --- a/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java @@ -18,4 +18,50 @@ import static org.junit.jupiter.api.Assertions.*; -class PersistenceInjectionModuleTest {} +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.persistence.storage.PersistenceStorageConfig; +import com.hedera.block.server.persistence.storage.read.BlockReader; +import com.hedera.block.server.persistence.storage.write.BlockWriter; +import com.hedera.block.server.util.TestConfigUtil; +import com.hedera.hapi.block.stream.Block; +import com.hedera.hapi.block.stream.BlockItem; +import java.io.IOException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class PersistenceInjectionModuleTest { + + @Mock private BlockNodeContext blockNodeContext; + + @Mock private PersistenceStorageConfig persistenceStorageConfig; + + @BeforeEach + void setup() throws IOException { + // Setup any necessary mocks before each test + blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); + persistenceStorageConfig = + blockNodeContext.configuration().getConfigData(PersistenceStorageConfig.class); + } + + @Test + void testProvidesBlockWriter() { + + BlockWriter blockWriter = + PersistenceInjectionModule.providesBlockWriter(blockNodeContext); + + assertNotNull(blockWriter); + } + + @Test + void testProvidesBlockReader() { + + BlockReader blockReader = + PersistenceInjectionModule.providesBlockReader(persistenceStorageConfig); + + assertNotNull(blockReader); + } +} From 689b6fcc426a7a98c6d3cd0ae20621689a1b48c4 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 21:26:49 -0600 Subject: [PATCH 13/17] Added UT for missing InjectionModules, removed unneeded configuration definition from ConfigExtensions Signed-off-by: Alfredo Gutierrez --- .../config/BlockNodeConfigExtension.java | 2 - .../server/config/ConfigInjectionModule.java | 13 --- .../BlockNodeAppInjectionModuleTest.java | 58 +++++++++++- .../config/ConfigInjectionModuleTest.java | 94 +++++++++++++++++++ .../metrics/MetricsInjectionModuleTest.java | 55 +++++++++++ 5 files changed, 202 insertions(+), 20 deletions(-) create mode 100644 server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java create mode 100644 server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java diff --git a/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java b/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java index d99c08b9..62065e39 100644 --- a/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java +++ b/server/src/main/java/com/hedera/block/server/config/BlockNodeConfigExtension.java @@ -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; @@ -44,7 +43,6 @@ public BlockNodeConfigExtension() { @Override public Set> getConfigDataTypes() { return Set.of( - BasicCommonConfig.class, MetricsConfig.class, PrometheusConfig.class, ConsumerConfig.class, diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java index 3e0ae7cf..db15f894 100644 --- a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -18,7 +18,6 @@ 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.Configuration; @@ -82,16 +81,4 @@ static PrometheusConfig providePrometheusConfig(@NonNull Configuration configura static ConsumerConfig provideConsumerConfig(@NonNull Configuration configuration) { return configuration.getConfigData(ConsumerConfig.class); } - - /** - * Provides a basic common configuration singleton using the configuration. - * - * @param configuration is the configuration singleton - * @return a basic common configuration singleton - */ - @Singleton - @Provides - static BasicCommonConfig provideBasicCommonConfig(@NonNull Configuration configuration) { - return configuration.getConfigData(BasicCommonConfig.class); - } } diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java index 27cabfc4..831fa88e 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java @@ -17,18 +17,66 @@ package com.hedera.block.server; import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.data.ObjectEvent; +import com.hedera.block.server.mediator.StreamMediator; +import com.hedera.block.server.metrics.MetricsService; +import com.hedera.block.server.persistence.storage.read.BlockReader; import com.hedera.block.server.util.TestConfigUtil; +import com.hedera.hapi.block.SubscribeStreamResponse; +import com.hedera.hapi.block.stream.Block; +import com.hedera.hapi.block.stream.BlockItem; +import com.swirlds.config.api.Configuration; +import io.helidon.webserver.WebServerConfig; import java.io.IOException; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mock; class BlockNodeAppInjectionModuleTest { + + @Mock private StreamMediator> streamMediator; + + @Mock private BlockReader blockReader; + + @Mock private ServiceStatus serviceStatus; + + private BlockNodeContext blockNodeContext; + + @BeforeEach + void setUp() throws IOException { + blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); + } + + @Test + void testProvideBlockNodeContext() { + Configuration configuration = blockNodeContext.configuration(); + MetricsService metricsService = blockNodeContext.metricsService(); + + BlockNodeContext providedBlockNodeContext = + BlockNodeAppInjectionModule.provideBlockNodeContext(configuration, metricsService); + + Assertions.assertEquals(blockNodeContext, providedBlockNodeContext); + Assertions.assertEquals( + blockNodeContext.configuration(), providedBlockNodeContext.configuration()); + Assertions.assertEquals( + blockNodeContext.metricsService(), providedBlockNodeContext.metricsService()); + } + + @Test + void testProvideBlockStreamService() { + BlockStreamService blockStreamService = + BlockNodeAppInjectionModule.provideBlockStreamService( + streamMediator, blockReader, serviceStatus, blockNodeContext); + + Assertions.assertNotNull(blockStreamService); + } + @Test - void testProvideBlockNodeContext() throws IOException { - BlockNodeContext blockNodeContext = TestConfigUtil.getTestBlockNodeContext(); + void testProvideWebServerConfigBuilder() { + WebServerConfig.Builder webServerConfigBuilder = + BlockNodeAppInjectionModule.provideWebServerConfigBuilder(); - Assertions.assertNotNull(blockNodeContext); - Assertions.assertNotNull(blockNodeContext.configuration()); - Assertions.assertNotNull(blockNodeContext.metricsService()); + Assertions.assertNotNull(webServerConfigBuilder); } } diff --git a/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java new file mode 100644 index 00000000..6c9d7505 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/config/ConfigInjectionModuleTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.config; + +import static org.junit.jupiter.api.Assertions.*; + +import com.hedera.block.server.consumer.ConsumerConfig; +import com.hedera.block.server.persistence.storage.PersistenceStorageConfig; +import com.hedera.block.server.util.TestConfigUtil; +import com.swirlds.common.metrics.config.MetricsConfig; +import com.swirlds.common.metrics.platform.prometheus.PrometheusConfig; +import com.swirlds.config.api.Configuration; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +class ConfigInjectionModuleTest { + + @Test + void testProvidePersistenceStorageConfig() throws IOException { + + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + PersistenceStorageConfig persistenceStorageConfig = + configuration.getConfigData(PersistenceStorageConfig.class); + + // Call the method under test + PersistenceStorageConfig providedConfig = + ConfigInjectionModule.providePersistenceStorageConfig(configuration); + + // Verify that the correct config data is returned + assertNotNull(providedConfig); + assertSame(persistenceStorageConfig, providedConfig); + } + + @Test + void testProvideMetricsConfig() throws IOException { + + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + MetricsConfig metricsConfig = configuration.getConfigData(MetricsConfig.class); + + // Call the method under test + MetricsConfig providedConfig = ConfigInjectionModule.provideMetricsConfig(configuration); + + // Verify that the correct config data is returned + assertNotNull(providedConfig); + assertSame(metricsConfig, providedConfig); + } + + @Test + void testProvidePrometheusConfig() throws IOException { + + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + PrometheusConfig prometheusConfig = configuration.getConfigData(PrometheusConfig.class); + + // Call the method under test + PrometheusConfig providedConfig = + ConfigInjectionModule.providePrometheusConfig(configuration); + + // Verify that the correct config data is returned + assertNotNull(providedConfig); + assertSame(prometheusConfig, providedConfig); + } + + @Test + void testProvideConsumerConfig() throws IOException { + + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + ConsumerConfig consumerConfig = configuration.getConfigData(ConsumerConfig.class); + + // Call the method under test + ConsumerConfig providedConfig = ConfigInjectionModule.provideConsumerConfig(configuration); + + // Verify that the correct config data is returned + assertNotNull(providedConfig); + assertSame(consumerConfig, providedConfig); + } +} diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java new file mode 100644 index 00000000..525ef747 --- /dev/null +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2024 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.block.server.metrics; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import com.hedera.block.server.config.BlockNodeContext; +import com.hedera.block.server.util.TestConfigUtil; +import com.swirlds.config.api.Configuration; +import com.swirlds.metrics.api.Metrics; +import java.io.IOException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class MetricsInjectionModuleTest { + + @Mock private Metrics metrics; + + @Test + void testProvideMetricsService() { + // Call the method under test + MetricsService metricsService = MetricsInjectionModule.provideMetricsService(metrics); + + // Verify that the metricsService is correctly instantiated + assertNotNull(metricsService); + } + + @Test + void testProvideMetrics() throws IOException { + BlockNodeContext context = TestConfigUtil.getTestBlockNodeContext(); + Configuration configuration = context.configuration(); + + // Call the method under test + Metrics providedMetrics = MetricsInjectionModule.provideMetrics(configuration); + + assertNotNull(providedMetrics); + } +} From 56af241e3b55d06bc2e9a041720facad68879679 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Sat, 24 Aug 2024 21:43:39 -0600 Subject: [PATCH 14/17] Last UT to complete coverage Signed-off-by: Alfredo Gutierrez --- .../PersistenceInjectionModuleTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java index 76641b76..70ed73e6 100644 --- a/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/persistence/PersistenceInjectionModuleTest.java @@ -17,6 +17,8 @@ package com.hedera.block.server.persistence; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import com.hedera.block.server.config.BlockNodeContext; import com.hedera.block.server.persistence.storage.PersistenceStorageConfig; @@ -25,6 +27,7 @@ import com.hedera.block.server.util.TestConfigUtil; import com.hedera.hapi.block.stream.Block; import com.hedera.hapi.block.stream.BlockItem; +import com.swirlds.config.api.Configuration; import java.io.IOException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -56,6 +59,26 @@ void testProvidesBlockWriter() { assertNotNull(blockWriter); } + @Test + void testProvidesBlockWriter_IOException() { + BlockNodeContext blockNodeContext = mock(BlockNodeContext.class); + PersistenceStorageConfig persistenceStorageConfig = mock(PersistenceStorageConfig.class); + when(persistenceStorageConfig.rootPath()).thenReturn("invalid-path*9/////+>"); + Configuration configuration = mock(Configuration.class); + when(blockNodeContext.configuration()).thenReturn(configuration); + when(configuration.getConfigData(PersistenceStorageConfig.class)) + .thenReturn(persistenceStorageConfig); + + // Expect a RuntimeException due to the IOException + RuntimeException exception = + assertThrows( + RuntimeException.class, + () -> PersistenceInjectionModule.providesBlockWriter(blockNodeContext)); + + // Verify the exception message + assertTrue(exception.getMessage().contains("Failed to create block writer")); + } + @Test void testProvidesBlockReader() { From 86ac482a5485f9eb7ede03a88e5daf1df531be67 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Mon, 26 Aug 2024 14:49:25 -0600 Subject: [PATCH 15/17] Settling for Factory instead of Builder when passing the configuration Signed-off-by: Alfredo Gutierrez --- .../BlockNodeAppInjectionComponent.java | 29 ++++++------------- .../java/com/hedera/block/server/Server.java | 4 +-- 2 files changed, 10 insertions(+), 23 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java index 05ed8be9..114bedc0 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionComponent.java @@ -45,29 +45,18 @@ public interface BlockNodeAppInjectionComponent { */ BlockNodeApp getBlockNodeApp(); - // @Component.Factory - // interface Factory { - // BlockNodeAppInjectionComponent create(@BindsInstance Configuration configuration); - // } - - /** Builder for the BlockNodeAppInjectionComponent. */ - @Component.Builder - interface Builder { - + /** + * 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 { /** - * Bind the configuration to the BlockNodeAppInjectionComponent. + * Create the block node app injection component. * * @param configuration the configuration - * @return the BlockNodeAppInjectionComponentBuilder - */ - @BindsInstance - Builder configuration(Configuration configuration); - - /** - * Build the BlockNodeAppInjectionComponent. - * - * @return the BlockNodeAppInjectionComponent + * @return the block node app injection component */ - BlockNodeAppInjectionComponent build(); + BlockNodeAppInjectionComponent create(@BindsInstance Configuration configuration); } } diff --git a/server/src/main/java/com/hedera/block/server/Server.java b/server/src/main/java/com/hedera/block/server/Server.java index 4c8b0413..51c8df1e 100644 --- a/server/src/main/java/com/hedera/block/server/Server.java +++ b/server/src/main/java/com/hedera/block/server/Server.java @@ -55,10 +55,8 @@ public static void main(final String[] args) throws IOException { // Init Dagger DI Component, passing in the configuration. // this is where all the dependencies are wired up (magic happens) - // final BlockNodeAppInjectionComponent daggerComponent = - // DaggerBlockNodeAppInjectionComponent.factory().create(configuration); final BlockNodeAppInjectionComponent daggerComponent = - DaggerBlockNodeAppInjectionComponent.builder().configuration(configuration).build(); + DaggerBlockNodeAppInjectionComponent.factory().create(configuration); // Use Dagger DI Component to start the BlockNodeApp with all wired dependencies final BlockNodeApp blockNodeApp = daggerComponent.getBlockNodeApp(); From 15076c5c7404b78cdfed06cec69de07b883fb32d Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Mon, 26 Aug 2024 15:32:08 -0600 Subject: [PATCH 16/17] Refactored GrpcProvider dagger bean to use the interface instead of the implementation, to be able to use Bind instead of Provide, deleted unneeded UT. Removed @NonNull annotation from injection module, since is redundant. Signed-off-by: Alfredo Gutierrez --- .../com/hedera/block/server/BlockNodeApp.java | 5 ++-- .../server/BlockNodeAppInjectionModule.java | 25 +++---------------- .../server/config/ConfigInjectionModule.java | 10 +++----- .../server/health/HealthInjectionModule.java | 3 +-- .../PersistenceInjectionModule.java | 5 ++-- .../BlockNodeAppInjectionModuleTest.java | 9 ------- 6 files changed, 14 insertions(+), 43 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java index 8bbcad0a..53b0d7e0 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeApp.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeApp.java @@ -24,6 +24,7 @@ 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; @@ -40,7 +41,7 @@ public class BlockNodeApp { private final ServiceStatus serviceStatus; private final HealthService healthService; - private final BlockStreamService blockStreamService; + private final GrpcService blockStreamService; private final WebServerConfig.Builder webServerBuilder; /** @@ -55,7 +56,7 @@ public class BlockNodeApp { public BlockNodeApp( @NonNull ServiceStatus serviceStatus, @NonNull HealthService healthService, - @NonNull BlockStreamService blockStreamService, + @NonNull GrpcService blockStreamService, @NonNull WebServerConfig.Builder webServerBuilder) { this.serviceStatus = serviceStatus; this.healthService = healthService; diff --git a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java index ddfa8692..023293f7 100644 --- a/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/BlockNodeAppInjectionModule.java @@ -17,19 +17,13 @@ package com.hedera.block.server; import com.hedera.block.server.config.BlockNodeContext; -import com.hedera.block.server.data.ObjectEvent; -import com.hedera.block.server.mediator.StreamMediator; import com.hedera.block.server.metrics.MetricsService; -import com.hedera.block.server.persistence.storage.read.BlockReader; -import com.hedera.hapi.block.SubscribeStreamResponse; -import com.hedera.hapi.block.stream.Block; -import com.hedera.hapi.block.stream.BlockItem; import com.swirlds.config.api.Configuration; import dagger.Binds; import dagger.Module; import dagger.Provides; -import edu.umd.cs.findbugs.annotations.NonNull; import io.helidon.webserver.WebServerConfig; +import io.helidon.webserver.grpc.GrpcService; import javax.inject.Singleton; /** @@ -66,23 +60,12 @@ static BlockNodeContext provideBlockNodeContext( /** * Provides a block stream service singleton using DI. * - * @param streamMediator should come from DI - * @param blockReader should come from DI - * @param serviceStatus should come from DI - * @param blockNodeContext should come from DI + * @param blockStreamService should come from DI * @return a block stream service singleton */ @Singleton - @Provides - static BlockStreamService provideBlockStreamService( - @NonNull - final StreamMediator> - streamMediator, - @NonNull final BlockReader blockReader, - @NonNull final ServiceStatus serviceStatus, - @NonNull final BlockNodeContext blockNodeContext) { - return new BlockStreamService(streamMediator, blockReader, serviceStatus, blockNodeContext); - } + @Binds + GrpcService bindBlockStreamService(BlockStreamService blockStreamService); /** * Provides a web server config builder singleton using DI. diff --git a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java index db15f894..94365187 100644 --- a/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/config/ConfigInjectionModule.java @@ -23,7 +23,6 @@ import com.swirlds.config.api.Configuration; import dagger.Module; import dagger.Provides; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.inject.Singleton; /** @@ -41,8 +40,7 @@ public interface ConfigInjectionModule { */ @Singleton @Provides - static PersistenceStorageConfig providePersistenceStorageConfig( - @NonNull Configuration configuration) { + static PersistenceStorageConfig providePersistenceStorageConfig(Configuration configuration) { return configuration.getConfigData(PersistenceStorageConfig.class); } @@ -54,7 +52,7 @@ static PersistenceStorageConfig providePersistenceStorageConfig( */ @Singleton @Provides - static MetricsConfig provideMetricsConfig(@NonNull Configuration configuration) { + static MetricsConfig provideMetricsConfig(Configuration configuration) { return configuration.getConfigData(MetricsConfig.class); } @@ -66,7 +64,7 @@ static MetricsConfig provideMetricsConfig(@NonNull Configuration configuration) */ @Singleton @Provides - static PrometheusConfig providePrometheusConfig(@NonNull Configuration configuration) { + static PrometheusConfig providePrometheusConfig(Configuration configuration) { return configuration.getConfigData(PrometheusConfig.class); } @@ -78,7 +76,7 @@ static PrometheusConfig providePrometheusConfig(@NonNull Configuration configura */ @Singleton @Provides - static ConsumerConfig provideConsumerConfig(@NonNull Configuration configuration) { + static ConsumerConfig provideConsumerConfig(Configuration configuration) { return configuration.getConfigData(ConsumerConfig.class); } } diff --git a/server/src/main/java/com/hedera/block/server/health/HealthInjectionModule.java b/server/src/main/java/com/hedera/block/server/health/HealthInjectionModule.java index db882c9b..377cbc53 100644 --- a/server/src/main/java/com/hedera/block/server/health/HealthInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/health/HealthInjectionModule.java @@ -18,7 +18,6 @@ import dagger.Binds; import dagger.Module; -import edu.umd.cs.findbugs.annotations.NonNull; import javax.inject.Singleton; /** @@ -36,5 +35,5 @@ public interface HealthInjectionModule { */ @Singleton @Binds - HealthService bindHealthService(@NonNull HealthServiceImpl healthService); + HealthService bindHealthService(HealthServiceImpl healthService); } diff --git a/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java b/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java index e9337b18..2cddc12b 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java +++ b/server/src/main/java/com/hedera/block/server/persistence/PersistenceInjectionModule.java @@ -26,7 +26,6 @@ import com.hedera.hapi.block.stream.BlockItem; import dagger.Module; import dagger.Provides; -import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import javax.inject.Singleton; @@ -42,7 +41,7 @@ public interface PersistenceInjectionModule { */ @Provides @Singleton - static BlockWriter providesBlockWriter(@NonNull BlockNodeContext blockNodeContext) { + static BlockWriter providesBlockWriter(BlockNodeContext blockNodeContext) { try { return BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build(); } catch (IOException e) { @@ -58,7 +57,7 @@ static BlockWriter providesBlockWriter(@NonNull BlockNodeContext bloc */ @Provides @Singleton - static BlockReader providesBlockReader(@NonNull PersistenceStorageConfig config) { + static BlockReader providesBlockReader(PersistenceStorageConfig config) { return BlockAsDirReaderBuilder.newBuilder(config).build(); } } diff --git a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java index 831fa88e..cfafca95 100644 --- a/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockNodeAppInjectionModuleTest.java @@ -63,15 +63,6 @@ void testProvideBlockNodeContext() { blockNodeContext.metricsService(), providedBlockNodeContext.metricsService()); } - @Test - void testProvideBlockStreamService() { - BlockStreamService blockStreamService = - BlockNodeAppInjectionModule.provideBlockStreamService( - streamMediator, blockReader, serviceStatus, blockNodeContext); - - Assertions.assertNotNull(blockStreamService); - } - @Test void testProvideWebServerConfigBuilder() { WebServerConfig.Builder webServerConfigBuilder = From 020dd927cf2bf0ef4306e266d6cd263b2e4dff66 Mon Sep 17 00:00:00 2001 From: Alfredo Gutierrez Date: Mon, 26 Aug 2024 18:07:40 -0600 Subject: [PATCH 17/17] Moved Application_Properties file to Constants Signed-off-by: Alfredo Gutierrez --- server/src/main/java/com/hedera/block/server/Constants.java | 3 +++ server/src/main/java/com/hedera/block/server/Server.java | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/com/hedera/block/server/Constants.java b/server/src/main/java/com/hedera/block/server/Constants.java index 5b9850af..8fbd6900 100644 --- a/server/src/main/java/com/hedera/block/server/Constants.java +++ b/server/src/main/java/com/hedera/block/server/Constants.java @@ -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"; diff --git a/server/src/main/java/com/hedera/block/server/Server.java b/server/src/main/java/com/hedera/block/server/Server.java index 51c8df1e..48b39490 100644 --- a/server/src/main/java/com/hedera/block/server/Server.java +++ b/server/src/main/java/com/hedera/block/server/Server.java @@ -31,7 +31,6 @@ public class Server { private static final Logger LOGGER = System.getLogger(Server.class.getName()); - private static final String APPLICATION_PROPERTIES = "app.properties"; private Server() {} @@ -49,7 +48,9 @@ public static void main(final String[] args) throws IOException { ConfigurationBuilder.create() .withSource(SystemEnvironmentConfigSource.getInstance()) .withSource(SystemPropertiesConfigSource.getInstance()) - .withSource(new ClasspathFileConfigSource(Path.of(APPLICATION_PROPERTIES))) + .withSource( + new ClasspathFileConfigSource( + Path.of(Constants.APPLICATION_PROPERTIES))) .autoDiscoverExtensions() .build();