From 19bf1f99f19be5aa09c78d2497c53d3b3106e5d7 Mon Sep 17 00:00:00 2001 From: jpe7s Date: Mon, 14 Oct 2024 07:35:46 -0500 Subject: [PATCH] add helius config parser and factory. --- solana/src/main/java/module-info.java | 13 +-- .../services/solana/config/HeliusConfig.java | 81 +++++++++++++++++++ 2 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 solana/src/main/java/software/sava/services/solana/config/HeliusConfig.java diff --git a/solana/src/main/java/module-info.java b/solana/src/main/java/module-info.java index d29eb31..a17600e 100644 --- a/solana/src/main/java/module-info.java +++ b/solana/src/main/java/module-info.java @@ -1,15 +1,18 @@ module software.sava.solana_services { - requires jdk.httpserver; requires java.net.http; + requires jdk.httpserver; requires systems.comodal.json_iterator; - requires software.sava.core_services; - requires software.sava.anchor_programs; - requires software.sava.solana_programs; - requires software.sava.rpc; + requires software.sava.core; + requires software.sava.rpc; + requires software.sava.solana_programs; + requires software.sava.solana_web2; + requires software.sava.anchor_programs; + requires software.sava.core_services; exports software.sava.services.solana.accounts.lookup; exports software.sava.services.solana.accounts.lookup.http; + exports software.sava.services.solana.config; exports software.sava.services.solana.load_balance; exports software.sava.services.solana.remote.call; } diff --git a/solana/src/main/java/software/sava/services/solana/config/HeliusConfig.java b/solana/src/main/java/software/sava/services/solana/config/HeliusConfig.java new file mode 100644 index 0000000..76f7021 --- /dev/null +++ b/solana/src/main/java/software/sava/services/solana/config/HeliusConfig.java @@ -0,0 +1,81 @@ +package software.sava.services.solana.config; + +import software.sava.services.core.remote.call.ErrorHandler; +import software.sava.services.core.remote.call.ErrorHandlerConfig; +import software.sava.services.core.remote.load_balance.BalancedItem; +import software.sava.services.core.remote.load_balance.LoadBalancer; +import software.sava.services.core.request_capacity.CapacityConfig; +import software.sava.services.core.request_capacity.ErrorTrackedCapacityMonitor; +import software.sava.solana.web2.helius.client.http.HeliusClient; +import systems.comodal.jsoniter.FieldBufferPredicate; +import systems.comodal.jsoniter.JsonIterator; +import systems.comodal.jsoniter.ValueType; + +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpResponse; +import java.util.Objects; + +import static java.util.Objects.requireNonNullElse; +import static systems.comodal.jsoniter.JsonIterator.fieldEquals; + +public record HeliusConfig(URI endpoint, + CapacityConfig capacityConfig, + ErrorHandler errorHandler) { + + public static HeliusConfig parseConfig(final JsonIterator ji) { + if (ji.whatIsNext() == ValueType.STRING) { + return new HeliusConfig(URI.create(ji.readString()), null, null); + } else { + final var parser = new Parser(); + ji.testObject(parser); + return parser.create(); + } + } + + public ErrorTrackedCapacityMonitor> createMonitor(final String serviceName, + final CapacityConfig defaultConfig) { + return requireNonNullElse(capacityConfig, defaultConfig).createHttpResponseMonitor(serviceName); + } + + public LoadBalancer createHeliusClient(final HttpClient httpClient, + final CapacityConfig defaultCapacityConfig, + final ErrorHandler defaultErrorHandler) { + final var capacityMonitor = createMonitor("helius", defaultCapacityConfig); + final var client = HeliusClient.createHttpClient(endpoint(), httpClient, capacityMonitor.errorTracker()); + final var balancedItem = BalancedItem.createItem( + client, + capacityMonitor, + Objects.requireNonNullElse(errorHandler, defaultErrorHandler) + ); + return LoadBalancer.createBalancer(balancedItem); + } + + private static final class Parser implements FieldBufferPredicate { + + private URI endpoint; + private CapacityConfig capacityConfig; + private ErrorHandler errorHandler; + + private Parser() { + } + + private HeliusConfig create() { + return new HeliusConfig(endpoint, capacityConfig, errorHandler); + } + + @Override + public boolean test(final char[] buf, final int offset, final int len, final JsonIterator ji) { + if (fieldEquals("url", buf, offset, len)) { + endpoint = URI.create(ji.readString()); + } else if (fieldEquals("capacity", buf, offset, len)) { + capacityConfig = CapacityConfig.parse(ji); + } else if (fieldEquals("backoff", buf, offset, len)) { + errorHandler = ErrorHandlerConfig.parseConfig(ji).createHandler(); + } else { + ji.skip(); + } + return true; + } + } +}