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 4ab2654e..8f16dd8b 100644 --- a/server/src/main/java/com/hedera/block/server/BlockStreamService.java +++ b/server/src/main/java/com/hedera/block/server/BlockStreamService.java @@ -202,7 +202,7 @@ private void singleBlock( fromPbjSingleBlockSuccessResponse(blockOpt.get())); final MetricsService metricsService = blockNodeContext.metricsService(); - metricsService.singleBlocksRetrieved.increment(); + metricsService.singleBlocksRetrieved().increment(); } else { LOGGER.log(DEBUG, "Block number {0} not found", blockNumber); singleBlockResponseStreamObserver.onNext(buildSingleBlockNotFoundResponse()); diff --git a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java index 587d2a7a..7feee6c3 100644 --- a/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java +++ b/server/src/main/java/com/hedera/block/server/mediator/LiveStreamMediatorImpl.java @@ -121,7 +121,7 @@ public void publish(@NonNull final BlockItem blockItem) throws IOException { ringBuffer.publishEvent((event, sequence) -> event.set(subscribeStreamResponse)); // Increment the block item counter - metricsService.liveBlockItems.increment(); + metricsService.liveBlockItems().increment(); try { // Persist the BlockItem @@ -211,7 +211,7 @@ private static SubscribeStreamResponse buildEndStreamResponse() { private void updateSubscriberMetrics() { @NonNull final MetricsService metricsService = blockNodeContext.metricsService(); - @NonNull final LongGauge longGauge = metricsService.subscribers; + @NonNull final LongGauge longGauge = metricsService.subscribers(); longGauge.set(subscribers.size()); } } 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 f65d3e8e..96c001ad 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 @@ -19,6 +19,7 @@ import com.swirlds.common.metrics.platform.DefaultMetricsProvider; import com.swirlds.config.api.Configuration; import com.swirlds.metrics.api.Metrics; +import dagger.Binds; import dagger.Module; import dagger.Provides; import javax.inject.Singleton; @@ -30,14 +31,12 @@ public interface MetricsInjectionModule { /** * Provides the metrics service. * - * @param metrics the metrics to be used by the service + * @param metricsService the metrics service to be used * @return the metrics service */ @Singleton - @Provides - static MetricsService provideMetricsService(Metrics metrics) { - return new MetricsService(metrics); - } + @Binds + MetricsService bindMetricsService(MetricsServiceImpl metricsService); /** * Provides the metrics. diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java index a383d8a0..6269a74e 100644 --- a/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsService.java @@ -18,57 +18,39 @@ import com.swirlds.metrics.api.Counter; import com.swirlds.metrics.api.LongGauge; -import com.swirlds.metrics.api.Metrics; import edu.umd.cs.findbugs.annotations.NonNull; -/** - * Use member variables of this class to update metric data for the Hedera Block Node. - * - *
Metrics are updated by calling the appropriate method on the metric object instance. For - * example, to increment a counter, call {@link Counter#increment()}. - */ -public class MetricsService { - - private static final String CATEGORY = "hedera_block_node"; - - // Live BlockItem Counter - private static final Counter.Config LIVE_BLOCK_ITEM_COUNTER = - new Counter.Config(CATEGORY, "live_block_items").withDescription("Live BlockItems"); - - // Block Persistence Counter - private static final Counter.Config BLOCK_PERSISTENCE_COUNTER = - new Counter.Config(CATEGORY, "blocks_persisted").withDescription("Blocks Persisted"); - - // Subscriber Gauge - private static final LongGauge.Config SUBSCRIBER_GAUGE = - new LongGauge.Config(CATEGORY, "subscribers").withDescription("Subscribers"); - - // Single Block Retrieved Counter - private static final Counter.Config SINGLE_BLOCK_RETRIEVED_COUNTER = - new Counter.Config(CATEGORY, "single_blocks_retrieved") - .withDescription("Single Blocks Retrieved"); - - /** Update the counter of live block items transiting via the live stream. */ - public final Counter liveBlockItems; - - /** Update the counter of blocks persisted to storage. */ - public final Counter blocksPersisted; +/** Use member variables of this class to update metric data for the Hedera Block Node. */ +public interface MetricsService { + /** + * Update the counter of live block items transiting via the live stream. + * + * @return use this metric to increase the counter of block items received + */ + @NonNull + Counter liveBlockItems(); - /** Update the counter of single blocks retrieved from storage. */ - public final Counter singleBlocksRetrieved; + /** + * Update the counter of blocks persisted to storage. + * + * @return use this counter to increase the amount of blocks persisted to disk + */ + @NonNull + Counter blocksPersisted(); - /** Update the gauge of subscribers currently consuming to the live stream. */ - public final LongGauge subscribers; + /** + * Update the counter of single blocks retrieved from storage. + * + * @return use this metric to increase the counter of single blocks retrieved + */ + @NonNull + Counter singleBlocksRetrieved(); /** - * Create singleton instance of metrics service to be used throughout the application. + * Update the gauge of subscribers currently consuming to the live stream. * - * @param metrics the metrics instance + * @return Use this to increase or decrease the amount of current subscribers to the live stream */ - public MetricsService(@NonNull final Metrics metrics) { - this.liveBlockItems = metrics.getOrCreate(LIVE_BLOCK_ITEM_COUNTER); - this.blocksPersisted = metrics.getOrCreate(BLOCK_PERSISTENCE_COUNTER); - this.singleBlocksRetrieved = metrics.getOrCreate(SINGLE_BLOCK_RETRIEVED_COUNTER); - this.subscribers = metrics.getOrCreate(SUBSCRIBER_GAUGE); - } + @NonNull + LongGauge subscribers(); } diff --git a/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java new file mode 100644 index 00000000..a05052df --- /dev/null +++ b/server/src/main/java/com/hedera/block/server/metrics/MetricsServiceImpl.java @@ -0,0 +1,100 @@ +/* + * 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.metrics.api.Counter; +import com.swirlds.metrics.api.LongGauge; +import com.swirlds.metrics.api.Metrics; +import edu.umd.cs.findbugs.annotations.NonNull; +import javax.inject.Inject; + +/** + * Use member variables of this class to update metric data for the Hedera Block Node. + * + *
Metrics are updated by calling the appropriate method on the metric object instance. For + * example, to increment a counter, call {@link Counter#increment()}. + */ +public class MetricsServiceImpl implements MetricsService { + + private static final String CATEGORY = "hedera_block_node"; + + // Live BlockItem Counter + private static final Counter.Config LIVE_BLOCK_ITEM_COUNTER = + new Counter.Config(CATEGORY, "live_block_items").withDescription("Live BlockItems"); + + // Block Persistence Counter + private static final Counter.Config BLOCK_PERSISTENCE_COUNTER = + new Counter.Config(CATEGORY, "blocks_persisted").withDescription("Blocks Persisted"); + + // Subscriber Gauge + private static final LongGauge.Config SUBSCRIBER_GAUGE = + new LongGauge.Config(CATEGORY, "subscribers").withDescription("Subscribers"); + + // Single Block Retrieved Counter + private static final Counter.Config SINGLE_BLOCK_RETRIEVED_COUNTER = + new Counter.Config(CATEGORY, "single_blocks_retrieved") + .withDescription("Single Blocks Retrieved"); + + private final Counter liveBlockItems; + + private final Counter blocksPersisted; + + private final Counter singleBlocksRetrieved; + + private final LongGauge subscribers; + + /** Update the counter of live block items transiting via the live stream. */ + @Override + @NonNull + public final Counter liveBlockItems() { + return liveBlockItems; + } + + /** Update the counter of blocks persisted to storage. */ + @Override + @NonNull + public final Counter blocksPersisted() { + return blocksPersisted; + } + + /** Update the counter of single blocks retrieved from storage. */ + @Override + @NonNull + public final Counter singleBlocksRetrieved() { + return singleBlocksRetrieved; + } + + /** Update the gauge of subscribers currently consuming to the live stream. */ + @Override + @NonNull + public final LongGauge subscribers() { + return subscribers; + } + + /** + * Create singleton instance of metrics service to be used throughout the application. + * + * @param metrics the metrics instance + */ + @Inject + public MetricsServiceImpl(@NonNull final Metrics metrics) { + this.liveBlockItems = metrics.getOrCreate(LIVE_BLOCK_ITEM_COUNTER); + this.blocksPersisted = metrics.getOrCreate(BLOCK_PERSISTENCE_COUNTER); + this.singleBlocksRetrieved = metrics.getOrCreate(SINGLE_BLOCK_RETRIEVED_COUNTER); + this.subscribers = metrics.getOrCreate(SUBSCRIBER_GAUGE); + } +} diff --git a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java index fdb34642..91d7580a 100644 --- a/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java +++ b/server/src/main/java/com/hedera/block/server/persistence/storage/write/BlockAsDirWriter.java @@ -163,7 +163,7 @@ private void resetState(@NonNull final BlockItem blockItem) throws IOException { // Increment the block counter final MetricsService metricsService = blockNodeContext.metricsService(); - metricsService.blocksPersisted.increment(); + metricsService.blocksPersisted().increment(); } private void repairPermissions(@NonNull final Path path) throws IOException { diff --git a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java index 81d4a1f6..6f668682 100644 --- a/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java +++ b/server/src/test/java/com/hedera/block/server/BlockStreamServiceIntegrationTest.java @@ -230,7 +230,7 @@ public void testSubscribeBlockStream() throws IOException { streamObserver.onNext(fromPbj(publishStreamRequest)); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); verify(blockWriter, timeout(testTimeout).times(1)).write(blockItems.getFirst()); 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 ef257300..09fb091b 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 @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import com.hedera.block.server.metrics.MetricsService; +import com.hedera.block.server.metrics.MetricsServiceImpl; import com.swirlds.config.api.Configuration; import org.junit.jupiter.api.Test; @@ -28,7 +29,7 @@ class BlockNodeContextTest { @Test void BlockNodeContext_initializesWithMetricsAndConfiguration() { Configuration configuration = mock(Configuration.class); - MetricsService metricsService = mock(MetricsService.class); + MetricsService metricsService = mock(MetricsServiceImpl.class); BlockNodeContext context = new BlockNodeContext(metricsService, configuration); diff --git a/server/src/test/java/com/hedera/block/server/config/TestConfigBuilder.java b/server/src/test/java/com/hedera/block/server/config/TestConfigBuilder.java index fc627f50..b94c8481 100644 --- a/server/src/test/java/com/hedera/block/server/config/TestConfigBuilder.java +++ b/server/src/test/java/com/hedera/block/server/config/TestConfigBuilder.java @@ -166,6 +166,7 @@ public TestConfigBuilder withValue( * @return the created configuration */ @NonNull + @SuppressWarnings({"removal"}) public Configuration getOrCreateConfig() { try (final Locked ignore = configLock.lock()) { if (configuration == null) { 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 f182bf28..06b63ea7 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 @@ -131,7 +131,7 @@ public void testUnsubscribeEach() throws InterruptedException, IOException { "Expected the mediator to have unsubscribed observer3"); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(0, blockNodeContext.metricsService().liveBlockItems().get()); } @Test @@ -148,7 +148,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(blockItem); // Verify the counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Confirm the BlockStorage write method was // called despite the absence of subscribers @@ -201,7 +201,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) // Acting as a producer, notify the mediator of a new block streamMediator.publish(blockItem); - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) @@ -248,7 +248,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.unsubscribe(concreteObserver3); // Confirm the counter was never incremented - assertEquals(0, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(0, blockNodeContext.metricsService().liveBlockItems().get()); } @Test @@ -277,7 +277,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnCancel().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -313,7 +313,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) testConsumerBlockItemObserver.getOnClose().run(); // Verify the block item incremented the counter - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Verify the event made it to the consumer verify(serverCallStreamObserver, timeout(testTimeout).times(1)).setOnCancelHandler(any()); @@ -348,7 +348,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) streamMediator.publish(secondBlockItem); // Confirm the counter was incremented only once - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Confirm the BlockPersistenceHandler write method was only called // once despite the second block being published. 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 index 525ef747..21305a76 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsInjectionModuleTest.java @@ -25,23 +25,11 @@ 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(); diff --git a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java index 464e9b62..d198d293 100644 --- a/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java +++ b/server/src/test/java/com/hedera/block/server/metrics/MetricsServiceTest.java @@ -32,11 +32,11 @@ void MetricsService_initializesLiveBlockItemsCounter() { Counter liveBlockItems = mock(Counter.class); when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(liveBlockItems); - MetricsService service = new MetricsService(metrics); + MetricsService service = new MetricsServiceImpl(metrics); - assertEquals(liveBlockItems, service.liveBlockItems); + assertEquals(liveBlockItems, service.liveBlockItems()); - service.liveBlockItems.increment(); + service.liveBlockItems().increment(); verify(liveBlockItems, times(1)).increment(); } @@ -46,11 +46,11 @@ void MetricsService_initializesBlocksPersistedCounter() { Counter blocksPersisted = mock(Counter.class); when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(blocksPersisted); - MetricsService service = new MetricsService(metrics); + MetricsService service = new MetricsServiceImpl(metrics); - assertEquals(blocksPersisted, service.blocksPersisted); + assertEquals(blocksPersisted, service.blocksPersisted()); - service.blocksPersisted.increment(); + service.blocksPersisted().increment(); verify(blocksPersisted, times(1)).increment(); } @@ -60,11 +60,11 @@ void MetricsService_initializesSingleBlocksRetrievedCounter() { Counter singleBlocksRetrieved = mock(Counter.class); when(metrics.getOrCreate(any(Counter.Config.class))).thenReturn(singleBlocksRetrieved); - MetricsService service = new MetricsService(metrics); + MetricsService service = new MetricsServiceImpl(metrics); - assertEquals(singleBlocksRetrieved, service.singleBlocksRetrieved); + assertEquals(singleBlocksRetrieved, service.singleBlocksRetrieved()); - service.singleBlocksRetrieved.increment(); + service.singleBlocksRetrieved().increment(); verify(singleBlocksRetrieved, times(1)).increment(); } @@ -74,11 +74,11 @@ void MetricsService_initializesSubscribersGauge() { LongGauge subscribers = mock(LongGauge.class); when(metrics.getOrCreate(any(LongGauge.Config.class))).thenReturn(subscribers); - MetricsService service = new MetricsService(metrics); + MetricsService service = new MetricsServiceImpl(metrics); - assertEquals(subscribers, service.subscribers); + assertEquals(subscribers, service.subscribers()); - service.subscribers.set(5); + service.subscribers().set(5); verify(subscribers, times(1)).set(5); } } 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 c1d85232..9c6e7bca 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 @@ -179,7 +179,7 @@ blockWriter, blockNodeContext, new ServiceStatusImpl()) producerBlockItemObserver.onNext(fromPbj(publishStreamRequest)); // Confirm the block item counter was incremented - assertEquals(1, blockNodeContext.metricsService().liveBlockItems.get()); + assertEquals(1, blockNodeContext.metricsService().liveBlockItems().get()); // Confirm each subscriber was notified of the new block verify(streamObserver1, timeout(testTimeout).times(1)) 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 ef3789dc..4653035a 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 @@ -20,6 +20,7 @@ import com.hedera.block.server.config.TestConfigBuilder; import com.hedera.block.server.consumer.ConsumerConfig; import com.hedera.block.server.metrics.MetricsService; +import com.hedera.block.server.metrics.MetricsServiceImpl; import com.swirlds.common.metrics.platform.DefaultMetricsProvider; import com.swirlds.config.api.Configuration; import com.swirlds.config.extensions.sources.ClasspathFileConfigSource; @@ -60,7 +61,7 @@ public static BlockNodeContext getTestBlockNodeContext( Metrics metrics = getTestMetrics(testConfiguration); - MetricsService metricsService = new MetricsService(metrics); + MetricsService metricsService = new MetricsServiceImpl(metrics); return new BlockNodeContext(metricsService, testConfiguration); }