Skip to content

Commit

Permalink
Initial Dagger Refactor
Browse files Browse the repository at this point in the history
Signed-off-by: Alfredo Gutierrez <[email protected]>
  • Loading branch information
AlfredoG87 committed Aug 21, 2024
1 parent 7f7cc7b commit d1b5d62
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 89 deletions.
143 changes: 143 additions & 0 deletions server/src/main/java/com/hedera/block/server/BlockNodeApp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
* 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 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.health.HealthService;
import com.hedera.block.server.mediator.LiveStreamMediatorBuilder;
import com.hedera.block.server.mediator.StreamMediator;
import com.hedera.block.server.persistence.storage.PersistenceStorageConfig;
import com.hedera.block.server.persistence.storage.read.BlockAsDirReaderBuilder;
import com.hedera.block.server.persistence.storage.read.BlockReader;
import com.hedera.block.server.persistence.storage.write.BlockAsDirWriterBuilder;
import com.hedera.block.server.persistence.storage.write.BlockWriter;
import com.hedera.block.server.producer.ItemAckBuilder;
import edu.umd.cs.findbugs.annotations.NonNull;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.grpc.GrpcRouting;
import io.helidon.webserver.http.HttpRouting;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;

/**
* The main class for the Block Node application. This class is responsible for starting the server
* and initializing the context.
*/
@Singleton
public class BlockNodeApp {

private static final System.Logger LOGGER = System.getLogger(Server.class.getName());

Check warning on line 46 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L46

Added line #L46 was not covered by tests
private final ServiceStatus serviceStatus;
private final HealthService healthService;

/**
* Has all needed dependencies to start the server and initialize the context.
*
* @param serviceStatus the status of the service
* @param healthService the health service
*/
@Inject
public BlockNodeApp(
@NonNull ServiceStatus serviceStatus, @NonNull HealthService healthService) {
this.serviceStatus = serviceStatus;
this.healthService = healthService;
}

Check warning on line 61 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L58-L61

Added lines #L58 - L61 were not covered by tests

/**
* Starts the server and binds to the specified port.
*
* @throws IOException if the server cannot be started
*/
public void startServer() throws IOException {
// init context, metrics, and configuration.
@NonNull final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create();

Check warning on line 70 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L70

Added line #L70 was not covered by tests

@NonNull
final BlockWriter<com.hedera.block.protos.BlockStreamService.BlockItem> blockWriter =
BlockAsDirWriterBuilder.newBuilder(blockNodeContext).build();

Check warning on line 74 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L73-L74

Added lines #L73 - L74 were not covered by tests
@NonNull
final StreamMediator<
com.hedera.block.protos.BlockStreamService.BlockItem,
ObjectEvent<
com.hedera.block.protos.BlockStreamService.SubscribeStreamResponse>>
streamMediator =
LiveStreamMediatorBuilder.newBuilder(

Check warning on line 81 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L80-L81

Added lines #L80 - L81 were not covered by tests
blockWriter, blockNodeContext, serviceStatus)
.build();

Check warning on line 83 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L83

Added line #L83 was not covered by tests

@NonNull
final BlockReader<com.hedera.block.protos.BlockStreamService.Block> blockReader =
BlockAsDirReaderBuilder.newBuilder(

Check warning on line 87 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L86-L87

Added lines #L86 - L87 were not covered by tests
blockNodeContext
.configuration()
.getConfigData(PersistenceStorageConfig.class))
.build();

Check warning on line 91 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L89-L91

Added lines #L89 - L91 were not covered by tests

@NonNull
final BlockStreamService blockStreamService =
buildBlockStreamService(

Check warning on line 95 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L94-L95

Added lines #L94 - L95 were not covered by tests
streamMediator, blockReader, serviceStatus, blockNodeContext);

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

Check warning on line 99 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L99

Added line #L99 was not covered by tests

@NonNull
final HttpRouting.Builder httpRouting =
HttpRouting.builder().register(healthService.getHealthRootPath(), healthService);

Check warning on line 103 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L103

Added line #L103 was not covered by tests

// Build the web server
// TODO: make port server a configurable value.
@NonNull
final WebServer webServer =
WebServer.builder()
.port(8080)
.addRouting(grpcRouting)
.addRouting(httpRouting)
.build();

Check warning on line 113 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L109-L113

Added lines #L109 - L113 were not covered by tests

// Update the serviceStatus with the web server
serviceStatus.setWebServer(webServer);

Check warning on line 116 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L116

Added line #L116 was not covered by tests

// Start the web server
webServer.start();

Check warning on line 119 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L119

Added line #L119 was not covered by tests

// Log the server status
LOGGER.log(
System.Logger.Level.INFO, "Block Node Server started at port: " + webServer.port());
}

Check warning on line 124 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L122-L124

Added lines #L122 - L124 were not covered by tests

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

return new BlockStreamService(

Check warning on line 140 in server/src/main/java/com/hedera/block/server/BlockNodeApp.java

View check run for this annotation

Codecov / codecov/patch

server/src/main/java/com/hedera/block/server/BlockNodeApp.java#L140

Added line #L140 was not covered by tests
new ItemAckBuilder(), streamMediator, blockReader, serviceStatus, blockNodeContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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 com.hedera.block.server.health.HealthInjectionModule;
import dagger.Component;
import javax.inject.Singleton;

/** The infrastructure used to manage the instances and inject them using Dagger */
@Singleton
@Component(
modules = {
BlockNodeAppInjectionModule.class,
HealthInjectionModule.class,
})
public interface BlockNodeAppInjectionComponent {
/**
* Get the block node app server.
*
* @return the block node app server
*/
BlockNodeApp getBlockNodeApp();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 dagger.Binds;
import dagger.Module;
import javax.inject.Singleton;

/**
* A Dagger Module for interfaces that are at the BlockNodeApp Level, should be temporary and
* everything should be inside its own modules.
*/
@Module
public interface BlockNodeAppInjectionModule {

/**
* Binds the service status to the service status implementation.
*
* @param serviceStatus needs a service status implementation
* @return the service status implementation
*/
@Singleton
@Binds
ServiceStatus bindServiceStatus(ServiceStatusImpl serviceStatus);
}
95 changes: 6 additions & 89 deletions server/src/main/java/com/hedera/block/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,7 @@

package com.hedera.block.server;

import static com.hedera.block.protos.BlockStreamService.*;

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.health.HealthService;
import com.hedera.block.server.health.HealthServiceImpl;
import com.hedera.block.server.mediator.LiveStreamMediatorBuilder;
import com.hedera.block.server.mediator.StreamMediator;
import com.hedera.block.server.persistence.storage.PersistenceStorageConfig;
import com.hedera.block.server.persistence.storage.read.BlockAsDirReaderBuilder;
import com.hedera.block.server.persistence.storage.read.BlockReader;
import com.hedera.block.server.persistence.storage.write.BlockAsDirWriterBuilder;
import com.hedera.block.server.persistence.storage.write.BlockWriter;
import com.hedera.block.server.producer.ItemAckBuilder;
import edu.umd.cs.findbugs.annotations.NonNull;
import io.helidon.webserver.WebServer;
import io.helidon.webserver.grpc.GrpcRouting;
import io.helidon.webserver.http.HttpRouting;
import java.io.IOException;

/** Main class for the block node server */
Expand All @@ -53,80 +35,15 @@ public static void main(final String[] args) {

LOGGER.log(System.Logger.Level.INFO, "Starting BlockNode Server");

try {
// init context, metrics, and configuration.
@NonNull final BlockNodeContext blockNodeContext = BlockNodeContextFactory.create();

@NonNull final ServiceStatus serviceStatus = new ServiceStatusImpl();

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

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

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

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

@NonNull final HealthService healthService = new HealthServiceImpl(serviceStatus);
@NonNull
final BlockNodeAppInjectionComponent daggerComponent =
DaggerBlockNodeAppInjectionComponent.create();
@NonNull final BlockNodeApp server = daggerComponent.getBlockNodeApp();

@NonNull
final HttpRouting.Builder httpRouting =
HttpRouting.builder()
.register(healthService.getHealthRootPath(), healthService);

// Build the web server
// TODO: make port server a configurable value.
@NonNull
final WebServer webServer =
WebServer.builder()
.port(8080)
.addRouting(grpcRouting)
.addRouting(httpRouting)
.build();

// Update the serviceStatus with the web server
serviceStatus.setWebServer(webServer);

// Start the web server
webServer.start();

// Log the server status
LOGGER.log(
System.Logger.Level.INFO,
"Block Node Server started at port: " + webServer.port());
try {
server.startServer();
} catch (IOException e) {
throw new RuntimeException(e);
}
}

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

return new BlockStreamService(
new ItemAckBuilder(), streamMediator, blockReader, serviceStatus, blockNodeContext);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,21 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import io.helidon.webserver.WebServer;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import javax.inject.Singleton;

/**
* The ServiceStatusImpl class implements the ServiceStatus interface. It provides the
* implementation for checking the status of the service and shutting down the web server.
*/
@Singleton
public class ServiceStatusImpl implements ServiceStatus {

private final AtomicBoolean isRunning = new AtomicBoolean(true);
private WebServer webServer;

/** Constructor for the ServiceStatusImpl class. */
@Inject
public ServiceStatusImpl() {}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.health;

import dagger.Binds;
import dagger.Module;
import edu.umd.cs.findbugs.annotations.NonNull;
import javax.inject.Singleton;

/**
* A Dagger module for providing dependencies for Health Module, should we refactor to have an
* observability module instead?.
*/
@Module
public interface HealthInjectionModule {

/**
* Binds the health service to the health service implementation.
*
* @param healthService needs a health service implementation
* @return the health service implementation
*/
@Singleton
@Binds
HealthService bindHealthService(@NonNull HealthServiceImpl healthService);
}
Loading

0 comments on commit d1b5d62

Please sign in to comment.