diff --git a/pom.xml b/pom.xml
index a2a88ad..4e19041 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,18 +40,18 @@
1.3
- 3.12.4
- 5.7.2
- 1.8.0-RC1
- 5.8.0-RC1
- 1.48
+ 4.5.1
+ 5.8.2
+ 1.8.2
+ 5.8.2
+ 1.49
UTF-8
- 2.17.1
- 1.12.73
+ 2.17.2
+ 1.12.237
1.2.1
- 1.2.0
- 1.12.73
- 2.14.0-beta.1
+ 1.5.1
+ 1.12.237
+ 2.17.3
@@ -71,7 +71,7 @@
com.fasterxml.jackson.core
jackson-databind
- 2.12.6.1
+ 2.13.3
org.jmockit
@@ -93,7 +93,7 @@
org.apache.commons
commons-math3
- 3.5
+ 3.6.1
@@ -152,13 +152,16 @@
${mockito.version}
test
-
-
-
com.hedera.hashgraph
- sdk-jdk7
- ${hedera-java-sdk.version}
+ sdk-full
+ 2.16.1
+
+
+
+ io.grpc
+ grpc-netty-shaded
+ 1.46.0
com.amazonaws
@@ -183,34 +186,48 @@
javax.xml.bind
jaxb-api
- 2.3.0
-
-
-
- com.google.cloud
- google-cloud-spanner
- 1.33.0
-
-
- com.google.cloud
- google-cloud-storage
- 1.88.0
+ 2.3.1
org.flywaydb
flyway-core
- 7.4.0
+ 8.5.11
org.bouncycastle
bcprov-jdk15on
- 1.67
+ 1.70
org.postgresql
postgresql
- 42.3.3
+ 42.3.4
+
+
+ com.google.cloud
+ google-cloud-storage
+ 2.8.1
+
+
+ com.google.cloud
+ google-cloud-pubsub
+ 1.119.1
+
+
+ com.google.cloud.functions
+ functions-framework-api
+ 1.0.4
+
+
+ com.google.cloud.sql
+ postgres-socket-factory
+ 1.6.1
+
+
+ com.zaxxer
+ HikariCP
+ 5.0.1
@@ -238,7 +255,23 @@
${project.artifactId}
+
+
+ com.google.cloud.functions
+ function-maven-plugin
+ 0.10.0
+
+ com.hedera.exchange.ERTGcp
+
+
@@ -297,7 +330,30 @@
-
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+
+
+ package
+ shade
+
+ ${project.build.directory}/deployment/${project.build.finalName}.jar
+
+
+
+ .SF
+ .DSA
+ .RSA
+
+
+
+
+
+
+
+
org.apache.maven.plugins
maven-shade-plugin
diff --git a/src/main/java/com/hedera/exchange/ERTAws.java b/src/main/java/com/hedera/exchange/ERTAws.java
new file mode 100644
index 0000000..dbee211
--- /dev/null
+++ b/src/main/java/com/hedera/exchange/ERTAws.java
@@ -0,0 +1,62 @@
+package com.hedera.exchange;
+
+/*-
+ *
+ * Hedera Exchange Rate Tool
+ *
+ * Copyright (C) 2019 - 2020 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.
+ *
+ *
+ * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import static com.hedera.exchange.ExchangeRateTool.AWS_TAG;
+
+public class ERTAws {
+ public static void main(final String ... args) {
+ ExchangeRateTool ert = new ExchangeRateTool();
+ ert.run(AWS_TAG);
+ }
+}
diff --git a/src/main/java/com/hedera/exchange/database/AWSDBParams.java b/src/main/java/com/hedera/exchange/ERTGcp.java
similarity index 80%
rename from src/main/java/com/hedera/exchange/database/AWSDBParams.java
rename to src/main/java/com/hedera/exchange/ERTGcp.java
index affa2a4..fe571f0 100644
--- a/src/main/java/com/hedera/exchange/database/AWSDBParams.java
+++ b/src/main/java/com/hedera/exchange/ERTGcp.java
@@ -1,4 +1,4 @@
-package com.hedera.exchange.database;
+package com.hedera.exchange;
/*-
*
@@ -52,22 +52,16 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-import com.hedera.exchange.ERTUtils;
+import com.google.cloud.functions.HttpFunction;
+import com.google.cloud.functions.HttpRequest;
+import com.google.cloud.functions.HttpResponse;
-public class AWSDBParams {
- public String getEndpoint() {
- return ERTUtils.getDecryptedEnvironmentVariableFromAWS("ENDPOINT") + getDatabaseName();
- }
-
- public String getUsername() {
- return ERTUtils.getDecryptedEnvironmentVariableFromAWS("USERNAME");
- }
-
- public String getPassword() {
- return ERTUtils.getDecryptedEnvironmentVariableFromAWS("PASSWORD");
- }
+import static com.hedera.exchange.ExchangeRateTool.GCP_TAG;
- public String getDatabaseName() {
- return ERTUtils.getDecryptedEnvironmentVariableFromAWS("DATABASE");
+public class ERTGcp implements HttpFunction {
+ @Override
+ public void service(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception {
+ ExchangeRateTool ert = new ExchangeRateTool();
+ ert.run(GCP_TAG);
}
}
diff --git a/src/main/java/com/hedera/exchange/ERTNotificationHelper.java b/src/main/java/com/hedera/exchange/ERTNotificationHelper.java
index 335a12e..3533859 100644
--- a/src/main/java/com/hedera/exchange/ERTNotificationHelper.java
+++ b/src/main/java/com/hedera/exchange/ERTNotificationHelper.java
@@ -57,10 +57,23 @@
import com.amazonaws.services.sns.AmazonSNSClient;
import com.amazonaws.services.sns.AmazonSNSClientBuilder;
import com.amazonaws.services.sns.model.AmazonSNSException;
+import com.google.api.core.ApiFuture;
+import com.google.api.core.ApiFutureCallback;
+import com.google.api.core.ApiFutures;
+import com.google.api.gax.rpc.ApiException;
+import com.google.cloud.pubsub.v1.Publisher;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.protobuf.ByteString;
+import com.google.pubsub.v1.PubsubMessage;
+import com.google.pubsub.v1.TopicName;
import com.hedera.exchange.exchanges.Exchange;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
import static com.hedera.exchange.ERTUtils.getDecryptedEnvironmentVariableFromAWS;
public final class ERTNotificationHelper {
@@ -78,6 +91,70 @@ private ERTNotificationHelper() {
* Content of the Email
*/
public static void publishMessage(final String subject, final String message, final String region) {
+ if (ExchangeRateTool.env == Environment.AWS) {
+ publishMessageUsingSNS(subject, message, region);
+ } else {
+ try {
+ publishMessageUsingPubSub(List.of(subject, message));
+ } catch (InterruptedException ex) {
+ LOGGER.error(Exchange.EXCHANGE_FILTER, "failed to terminate PubSub publisher");
+ }
+ }
+ }
+
+ private static void publishMessageUsingPubSub(List messages) throws InterruptedException {
+ final var projectId = System.getenv("PROJECT_ID");
+ final var topicId = System.getenv("TOPIC_ID");
+ LOGGER.info(Exchange.EXCHANGE_FILTER, "projectId is : {}, topicId is {}", projectId, topicId);
+ TopicName topicName = TopicName.of(projectId, topicId);
+ Publisher publisher = null;
+
+ try {
+ publisher = Publisher.newBuilder(topicName).build();
+
+ for (var message : messages) {
+ ByteString data = ByteString.copyFromUtf8(message);
+ PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();
+
+ // Once published, returns a server-assigned message id (unique within the topic)
+ ApiFuture future = publisher.publish(pubsubMessage);
+
+ // Add an asynchronous callback to handle success / failure
+ ApiFutures.addCallback(
+ future,
+ new ApiFutureCallback<>() {
+
+ @Override
+ public void onFailure(Throwable throwable) {
+ if (throwable instanceof ApiException) {
+ ApiException apiException = ((ApiException) throwable);
+ // details on the API exception
+ System.out.println(apiException.getStatusCode().getCode());
+ System.out.println(apiException.isRetryable());
+ }
+ System.out.println("Error publishing message : " + message);
+ }
+
+ @Override
+ public void onSuccess(String messageId) {
+ // Once published, returns server-assigned message ids (unique within the topic)
+ System.out.println("Published message ID: " + messageId);
+ }
+ },
+ MoreExecutors.directExecutor());
+ }
+ } catch (IOException ex) {
+ LOGGER.error(Exchange.EXCHANGE_FILTER, "Failed to publish message");
+ } finally {
+ if (publisher != null) {
+ // When finished with the publisher, shutdown to free up resources.
+ publisher.shutdown();
+ publisher.awaitTermination(1, TimeUnit.MINUTES);
+ }
+ }
+ }
+
+ private static void publishMessageUsingSNS(final String subject, final String message, final String region) {
try {
final AmazonSNSClient SNS_CLIENT = (AmazonSNSClient) AmazonSNSClientBuilder.standard()
.withRegion(getValidRegion(region))
diff --git a/src/main/java/com/hedera/exchange/ERTParams.java b/src/main/java/com/hedera/exchange/ERTParams.java
index 7e2ad40..3ae7c1e 100644
--- a/src/main/java/com/hedera/exchange/ERTParams.java
+++ b/src/main/java/com/hedera/exchange/ERTParams.java
@@ -67,9 +67,8 @@
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.hedera.hashgraph.sdk.AccountId;
-import com.hedera.exchange.database.AWSDBParams;
import com.hedera.exchange.database.ExchangeDB;
-import com.hedera.exchange.database.ExchangeRateAWSRD;
+import com.hedera.exchange.database.QueryHelper;
import com.hedera.exchange.exchanges.Exchange;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -82,6 +81,8 @@
import java.util.Map;
import java.util.Set;
+import static com.hedera.exchange.ExchangeRateTool.env;
+
/**
* This class reads the parameters from the config file and provides get methods to fetch the configuration parameters.
*
@@ -151,12 +152,12 @@ public class ERTParams {
*/
public static ERTParams readConfig(final String[] args) throws IOException {
if (args == null || args.length == 0) {
- return readDefaultConfig();
+ return readDefaultConfigFromAWS();
}
final String configurationPath = args[0];
if (configurationPath == null || configurationPath.trim().length() < 1) {
- return readDefaultConfig();
+ return readDefaultConfigFromAWS();
}
LOGGER.debug("Using configuration file: {}", configurationPath);
@@ -170,19 +171,28 @@ public static ERTParams readConfig(final String[] args) throws IOException {
}
if (configurationPath.contains("TO_DECIDE:AWS_NodeAddressFormat")){
- return readDefaultConfig(configurationPath);
+ return readDefaultConfigFromAWS(configurationPath);
}
return readConfig(configurationPath);
}
+
+ public static ERTParams readConfig() throws IOException {
+ if (env == Environment.AWS) {
+ return readDefaultConfigFromAWS();
+ } else {
+ return readDefaultConfigFromGCP();
+ }
+ }
+
/**
* Reads the AWS instance address from the arguments and replaces the node address in the
* default configuration
* @param awsInstanceAddress
* @return ERTParams object
*/
- private static ERTParams readDefaultConfig(String awsInstanceAddress) throws IOException {
+ private static ERTParams readDefaultConfigFromAWS(String awsInstanceAddress) throws IOException {
final String defaultConfigUri = ERTUtils.getDecryptedEnvironmentVariableFromAWS("DEFAULT_CONFIG_URI");
ERTParams ertParams = readConfigFromAWSS3(defaultConfigUri);
@@ -198,11 +208,24 @@ private static ERTParams readDefaultConfig(String awsInstanceAddress) throws IOE
* @return ERTParams object
* @throws IOException
*/
- private static ERTParams readDefaultConfig() throws IOException {
+ private static ERTParams readDefaultConfigFromAWS() throws IOException {
final String defaultConfigUri = ERTUtils.getDecryptedEnvironmentVariableFromAWS("DEFAULT_CONFIG_URI");
return readConfigFromAWSS3(defaultConfigUri);
}
+ private static ERTParams readDefaultConfigFromGCP() throws IOException {
+ final var projectId = System.getenv("PROJECT_ID");
+ final var bucket = System.getenv("BUCKET_NAME");
+ final var config = System.getenv("CONFIG_PATH");
+ LOGGER.info("Reading configuration file from GCP: {}, {}, {}", projectId, bucket, config);
+ var options = StorageOptions.newBuilder().setProjectId(projectId).build();
+ var storage = options.getService();
+ var blob = storage.get(bucket, config);
+
+ return OBJECT_MAPPER.readValue(blob.getContent(), ERTParams.class);
+// return readConfig("src/main/resources/configIntegration.json");
+ }
+
/**
* Read Config file from the Amazon S3 bucket
* @param endpoint
@@ -404,7 +427,11 @@ public String getOperatorId() {
@JsonIgnore
public String getOperatorKey(String networkName) {
- return ERTUtils.getDecryptedEnvironmentVariableFromAWS("OPERATOR_KEY_" + networkName);
+ if (env == Environment.AWS) {
+ return ERTUtils.getDecryptedEnvironmentVariableFromAWS("OPERATOR_KEY_" + networkName);
+ } else {
+ return System.getenv("OPERATOR_KEY_" + networkName);
+ }
}
/**
@@ -428,7 +455,7 @@ public long getValidationDelayInMilliseconds() {
* @return ExchangeRateDb object as we are configured with AWS POSTGRESQL for now.
*/
public ExchangeDB getExchangeDB() {
- return new ExchangeRateAWSRD(new AWSDBParams());
+ return new QueryHelper();
}
/**
diff --git a/src/main/java/com/hedera/exchange/ERTUtils.java b/src/main/java/com/hedera/exchange/ERTUtils.java
index 3b56623..1bbc40c 100644
--- a/src/main/java/com/hedera/exchange/ERTUtils.java
+++ b/src/main/java/com/hedera/exchange/ERTUtils.java
@@ -88,7 +88,7 @@
import java.util.List;
import java.util.Map;
-import static com.hedera.exchange.ExchangeRateTool.LAMBDA_FUNCTION_NAME;
+import static com.hedera.exchange.ExchangeRateTool.FUNCTION_NAME;
/**
* This class implements helper functions of ERT
@@ -132,7 +132,7 @@ private ERTUtils() {
*/
public static String getDecryptedEnvironmentVariableFromAWS(final String environmentVariable) {
final String environmentValue = System.getenv(environmentVariable);
- return getDecryptedValueFromAWS(environmentValue, LAMBDA_FUNCTION_NAME);
+ return getDecryptedValueFromAWS(environmentValue, FUNCTION_NAME);
}
static String getDecryptedValueFromAWS(final String value, final String lambdaFunctionName) {
diff --git a/src/main/java/com/hedera/exchange/Environment.java b/src/main/java/com/hedera/exchange/Environment.java
new file mode 100644
index 0000000..0c540a2
--- /dev/null
+++ b/src/main/java/com/hedera/exchange/Environment.java
@@ -0,0 +1,5 @@
+package com.hedera.exchange;
+
+public enum Environment {
+ AWS, GCP
+}
diff --git a/src/main/java/com/hedera/exchange/ExchangeRateTool.java b/src/main/java/com/hedera/exchange/ExchangeRateTool.java
index 0596ce5..64e307c 100644
--- a/src/main/java/com/hedera/exchange/ExchangeRateTool.java
+++ b/src/main/java/com/hedera/exchange/ExchangeRateTool.java
@@ -60,7 +60,6 @@
import com.hedera.hashgraph.sdk.PrecheckStatusException;
import com.hedera.hashgraph.sdk.PrivateKey;
import com.hedera.hashgraph.sdk.ReceiptStatusException;
-import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -81,22 +80,21 @@
*
* @author Anirudh, Cesar
*/
-public class ExchangeRateTool {
+public class ExchangeRateTool{
private static final Logger LOGGER = LogManager.getLogger(ExchangeRateTool.class);
private static final Map EMPTY_MAP = Collections.emptyMap();
+ protected static final String AWS_TAG = "aws";
+ protected static final String GCP_TAG = "gcp";
+
static final int DEFAULT_RETRIES = 4;
- static final String LAMBDA_FUNCTION_NAME = System.getenv("AWS_LAMBDA_FUNCTION_NAME");
+ public static Environment env;
+ static String FUNCTION_NAME;
private ERTParams ertParams;
private ExchangeDB exchangeDB;
- public static void main(final String ... args) {
- ExchangeRateTool ert = new ExchangeRateTool();
- ert.run(args);
- }
-
/**
* This method executes the ERT logic and if an execution fails, it retries for the a fixed number of times
* mentioned in DEFAULT_RETRIES.
@@ -105,14 +103,33 @@ public static void main(final String ... args) {
protected void run(final String ... args) {
LOGGER.debug(Exchange.EXCHANGE_FILTER, "Starting ExchangeRateTool");
try {
- ertParams = ERTParams.readConfig(args);
+ env = validateTag(args);
+ FUNCTION_NAME = env == Environment.AWS ?
+ System.getenv("AWS_LAMBDA_FUNCTION_NAME") :
+ System.getenv("K_SERVICE");
+ ertParams = ERTParams.readConfig();
exchangeDB = ertParams.getExchangeDB();
execute();
} catch (Exception ex) {
- final var subject = "FAILED : ERT Run Failed on " + LAMBDA_FUNCTION_NAME;
+ final var subject = "FAILED : ERT Run Failed on " + FUNCTION_NAME;
final var message = ex.getMessage() + "\n";
LOGGER.error(Exchange.EXCHANGE_FILTER, subject, ex);
- ERTNotificationHelper.publishMessage(subject, message + ExceptionUtils.getStackTrace(ex), ertParams.getRegion());
+ ERTNotificationHelper.publishMessage(subject, message + ex.getMessage(), ertParams.getRegion());
+ }
+ }
+
+ private Environment validateTag(final String[] args) {
+ if (args == null) {
+ LOGGER.error(Exchange.EXCHANGE_FILTER, "invalid tag provided. Has to be one of {}, {}", GCP_TAG, AWS_TAG);
+ throw new IllegalArgumentException("Invalid tag provided. Has to be one of " + GCP_TAG + ", " + AWS_TAG);
+ }
+
+ if (args[0].matches(GCP_TAG)) {
+ LOGGER.info(Exchange.EXCHANGE_FILTER, "Running on GCP Cloud Functions");
+ return Environment.GCP;
+ } else {
+ LOGGER.info(Exchange.EXCHANGE_FILTER, "Running on AWS Lambda");
+ return Environment.AWS;
}
}
@@ -195,7 +212,7 @@ protected Status fileUpdateTransactionForNetwork(
final var nodesFromPrevRun = ertAddressBookFromPreviousRun != null ?
getNodesForClient(ertAddressBookFromPreviousRun.getNodes()) : EMPTY_MAP;
- final Map nodesForClient = nodesFromPrevRun.isEmpty() ? nodesFromPrevRun : nodesFromConfig;
+ final Map nodesForClient = !nodesFromPrevRun.isEmpty() ? nodesFromPrevRun : nodesFromConfig;
LOGGER.info(Exchange.EXCHANGE_FILTER, "Building a Hedera Client with nodes {} \n Account {}",
nodesForClient,
@@ -284,4 +301,9 @@ private Rate getCurrentRate(final ExchangeDB exchangeDb, final ERTParams params)
LOGGER.info(Exchange.EXCHANGE_FILTER, "Using default exchange rate as current exchange rate");
return params.getDefaultRate();
}
+
+ public static void main(final String ... args) {
+ ExchangeRateTool ert = new ExchangeRateTool();
+ ert.run("gcp");
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/hedera/exchange/HederaNetworkCommunicator.java b/src/main/java/com/hedera/exchange/HederaNetworkCommunicator.java
index f7be2f1..54859c4 100644
--- a/src/main/java/com/hedera/exchange/HederaNetworkCommunicator.java
+++ b/src/main/java/com/hedera/exchange/HederaNetworkCommunicator.java
@@ -69,7 +69,6 @@
import com.hedera.hashgraph.sdk.TransactionReceipt;
import com.hedera.hashgraph.sdk.TransactionResponse;
import com.hedera.hashgraph.sdk.proto.NodeAddressBook;
-import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -149,6 +148,7 @@ public ERTAddressBook updateExchangeRateFile(
LOGGER.info(Exchange.EXCHANGE_FILTER, "Balance before updating the Exchange Rate file: {}",
currentBalance.hbars.toString());
+// ERTAddressBook newAddressBook = new ERTAddressBook();
ERTAddressBook newAddressBook = fetchAddressBook(client);
updateExchangeRateFileTxn(exchangeRate, exchangeRateFileId, exchangeRateAsBytes, client, memo, ertParams.getRegion());
@@ -257,8 +257,8 @@ private void updateExchangeRateFileTxn(
}
} catch (PrecheckStatusException ex) {
var subject = String.format("ERROR : %s : PreCheckStatusException : %s", networkName, ex.status);
- LOGGER.error(Exchange.EXCHANGE_FILTER, subject);
- ERTNotificationHelper.publishMessage(subject, ExceptionUtils.getStackTrace(ex), region);
+ LOGGER.error(Exchange.EXCHANGE_FILTER, subject, ex);
+ ERTNotificationHelper.publishMessage(subject, ex.getMessage(), region);
if( retryCount++ == DEFAULT_RETRIES ) {
throw ex;
}
@@ -353,8 +353,8 @@ private byte[] getFileContentsQuery(final Client client, final FileId fileId) th
final Hbar getContentsQueryFee = new FileContentsQuery()
.setFileId(fileId)
.getCost(client);
- LOGGER.debug(Exchange.EXCHANGE_FILTER, "Cost to get file {} contents is : {}", fileId, getContentsQueryFee);
- client.setDefaultMaxQueryPayment(getContentsQueryFee);
+ LOGGER.info(Exchange.EXCHANGE_FILTER, "Cost to get file {} contents is : {}", fileId, getContentsQueryFee);
+ client.setDefaultMaxQueryPayment(Hbar.from(1L));
final ByteString contentsResponse = new FileContentsQuery()
.setFileId(fileId)
diff --git a/src/main/java/com/hedera/exchange/api/ExchangeRateAPI.java b/src/main/java/com/hedera/exchange/api/ExchangeRateAPI.java
index 78a24fd..a2d6415 100644
--- a/src/main/java/com/hedera/exchange/api/ExchangeRateAPI.java
+++ b/src/main/java/com/hedera/exchange/api/ExchangeRateAPI.java
@@ -52,14 +52,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+import com.hedera.exchange.Environment;
import com.hedera.exchange.ExchangeRate;
-import com.hedera.exchange.database.AWSDBParams;
+import com.hedera.exchange.ExchangeRateTool;
+import com.hedera.exchange.database.DBParams;
import com.hedera.exchange.database.ExchangeDB;
-import com.hedera.exchange.database.ExchangeRateAWSRD;
+import com.hedera.exchange.database.QueryHelper;
import java.util.HashMap;
import java.util.Map;
+import static com.hedera.exchange.Environment.AWS;
+
/**
* This class implements an API that one can trigger using an AWS lambda for example and get the latest Exchange rate file
* from the database.
@@ -75,7 +79,9 @@ public class ExchangeRateAPI {
}
public static LambdaResponse getLatest() throws Exception {
- final ExchangeDB exchangeDb = new ExchangeRateAWSRD(new AWSDBParams());
+ // currently only supported on AWS
+ ExchangeRateTool.env = AWS;
+ final ExchangeDB exchangeDb = new QueryHelper();
final ExchangeRate latestExchangeRate = exchangeDb.getLatestExchangeRate();
if (latestExchangeRate == null) {
return new LambdaResponse(200, "No exchange rate available yet");
diff --git a/src/main/java/com/hedera/exchange/api/ExchangeRateHistoryAPI.java b/src/main/java/com/hedera/exchange/api/ExchangeRateHistoryAPI.java
index 51142e3..e8d09c4 100644
--- a/src/main/java/com/hedera/exchange/api/ExchangeRateHistoryAPI.java
+++ b/src/main/java/com/hedera/exchange/api/ExchangeRateHistoryAPI.java
@@ -59,11 +59,13 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import com.hedera.exchange.Environment;
import com.hedera.exchange.ExchangeRate;
+import com.hedera.exchange.ExchangeRateTool;
import com.hedera.exchange.Rate;
-import com.hedera.exchange.database.AWSDBParams;
+import com.hedera.exchange.database.DBParams;
import com.hedera.exchange.database.ExchangeDB;
-import com.hedera.exchange.database.ExchangeRateAWSRD;
+import com.hedera.exchange.database.QueryHelper;
import com.hedera.exchange.exchanges.Exchange;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -88,6 +90,8 @@
import java.util.Map;
import java.util.TimeZone;
+import static com.hedera.exchange.Environment.AWS;
+
/**
* This class implements an API which returns the data from the last 'n'[defaulted to 5] successful runs of ERT
*
@@ -128,8 +132,9 @@ public void handleRequest(InputStream inputStream, OutputStream outputStream, Co
no_of_records = Integer.parseInt((String) queryStringParameters.get("no_of_records"));
}
}
-
- final ExchangeDB exchangeDb = new ExchangeRateAWSRD(new AWSDBParams());
+ // currently only supported on AWS
+ ExchangeRateTool.env = AWS;
+ final ExchangeDB exchangeDb = new QueryHelper();
LOGGER.info(Exchange.EXCHANGE_FILTER, "params received : {}", no_of_records);
NO_OF_RECORDS = no_of_records;
ExchangeRate midnightRate = exchangeDb.getLatestMidnightExchangeRate();
diff --git a/src/main/java/com/hedera/exchange/database/DBParams.java b/src/main/java/com/hedera/exchange/database/DBParams.java
new file mode 100644
index 0000000..3e59df2
--- /dev/null
+++ b/src/main/java/com/hedera/exchange/database/DBParams.java
@@ -0,0 +1,133 @@
+package com.hedera.exchange.database;
+
+/*-
+ *
+ * Hedera Exchange Rate Tool
+ *
+ * Copyright (C) 2019 - 2020 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.
+ *
+ *
+ * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of JSR-310 nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import com.hedera.exchange.ERTUtils;
+import com.hedera.exchange.Environment;
+import com.hedera.exchange.exchanges.Exchange;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+import static com.hedera.exchange.ExchangeRateTool.env;
+
+public final class DBParams {
+ private static final Logger LOGGER = LogManager.getLogger(DBParams.class);
+
+ public DBParams() {
+ throw new UnsupportedOperationException("Utility Class");
+ }
+
+ public static String getEndpoint() {
+ if (env == Environment.AWS) {
+ return ERTUtils.getDecryptedEnvironmentVariableFromAWS("ENDPOINT") + getDatabaseName();
+ }
+ else {
+ LOGGER.error(Exchange.EXCHANGE_FILTER, "should not be possible");
+ return System.getenv("ENDPOINT") + getDatabaseName();
+ }
+ }
+
+ public static String getUsername() {
+ if (env == Environment.AWS) {
+ return ERTUtils.getDecryptedEnvironmentVariableFromAWS("USERNAME");
+ }
+ else {
+ return System.getenv("USERNAME");
+ }
+ }
+
+ public static String getPassword() {
+ if (env == Environment.AWS) {
+ return ERTUtils.getDecryptedEnvironmentVariableFromAWS("PASSWORD");
+ }
+ else {
+ return System.getenv("PASSWORD");
+ }
+ }
+
+ public static String getDatabaseName() {
+ if (env == Environment.AWS) {
+ return ERTUtils.getDecryptedEnvironmentVariableFromAWS("DATABASE");
+ }
+ else {
+ return System.getenv("DATABASE");
+ }
+ }
+
+ public static Connection getConnection() throws SQLException {
+ if (env == Environment.AWS) {
+ return DriverManager.getConnection(getEndpoint(), getUsername(), getPassword());
+ } else {
+ DataSource pool = getGcpDataSource();
+ return pool.getConnection();
+ }
+ }
+
+ public static DataSource getGcpDataSource() {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl(String.format("jdbc:postgresql:///%s", getDatabaseName()));
+ config.setUsername(getUsername());
+ config.setPassword(getPassword());
+ config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.postgres.SocketFactory");
+ config.addDataSourceProperty("cloudSqlInstance", System.getenv("INSTANCE_CONNECTION_NAME"));
+ config.addDataSourceProperty("ipTypes", "PUBLIC,PRIVATE");
+ return new HikariDataSource(config);
+ }
+}
diff --git a/src/main/java/com/hedera/exchange/database/GCPExchangeRateDB.java b/src/main/java/com/hedera/exchange/database/GCPExchangeRateDB.java
deleted file mode 100644
index 1f1a5fe..0000000
--- a/src/main/java/com/hedera/exchange/database/GCPExchangeRateDB.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package com.hedera.exchange.database;
-
-/*-
- *
- * Hedera Exchange Rate Tool
- *
- * Copyright (C) 2019 - 2020 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.
- *
- *
- * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of JSR-310 nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-import com.google.cloud.spanner.*;
-import com.hedera.exchange.ExchangeRate;
-
-public class GCPExchangeRateDB {
-
- // copy instance and db id from spanner website
- private static final String projectId = "ert-public-test-1";
- private static final String instanceId = "ert-spanner-instance";
- private static final String databaseId = "ert_data";
-
- public static void pushExchangeRate(ExchangeRate exchangeRate){
- // Instantiates a client
- SpannerOptions options = SpannerOptions.newBuilder().setProjectId(projectId).build();
- Spanner spanner = options.getService();
- try{
- // Creates a database client
- DatabaseClient dbClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
-
- String sql = String.format("INSERT INTO ExchangeRate (ExpirationTime, ExchagneRateData) values ('{}', {})",
- exchangeRate.getNextExpirationTimeInSeconds(), exchangeRate.toString());
-
- dbClient.readWriteTransaction().run(
- new TransactionRunner.TransactionCallable() {
- @Override
- public Void run(TransactionContext transaction) throws Exception {
- long rowCount = transaction.executeUpdate(Statement.of(sql));
- System.out.printf("%d record inserted.\n", rowCount);
- return null;
- }
- }
- );
-
- }
- catch( Exception e ){
- System.out.println("Writing to DB failed : " + e.getMessage());
- }
- finally {
- spanner.close();
- }
- }
-
- public static void pushMidnightExchangeRate(ExchangeRate exchangeRate){
- // Instantiates a client
- SpannerOptions options = SpannerOptions.newBuilder().setProjectId(projectId).build();
- Spanner spanner = options.getService();
- try{
- // Creates a database client
- DatabaseClient dbClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
-
- String sql = String.format("INSERT INTO MidnightExchangeRate (ExpirationTime, ExchangeRateData) values ('{}', {})",
- exchangeRate.getNextExpirationTimeInSeconds(), exchangeRate.toJson());
-
- dbClient.readWriteTransaction().run(
- new TransactionRunner.TransactionCallable() {
- @Override
- public Void run(TransactionContext transaction) throws Exception {
- long rowCount = transaction.executeUpdate(Statement.of(sql));
- System.out.printf("%d record inserted.\n", rowCount);
- return null;
- }
- }
- );
-
- }
- catch( Exception e ){
- System.out.println("Writing to DB failed : " + e.getMessage());
- }
- finally {
- spanner.close();
- }
- }
-
- // TODO build a DS to hold all the queries to exchanges and data they sent back
- public static void pushQueriedExchangesData(){
- // Instantiates a client
- SpannerOptions options = SpannerOptions.newBuilder().setProjectId(projectId).build();
- Spanner spanner = options.getService();
- try{
- // Creates a database client
- DatabaseClient dbClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
-
- String sql = String.format("INSERT INTO ExcahngesData (ExpirationTime, ExchangesData) values ('{}', {})",
- "" , "");
-
- dbClient.readWriteTransaction().run(
- new TransactionRunner.TransactionCallable() {
- @Override
- public Void run(TransactionContext transaction) throws Exception {
- long rowCount = transaction.executeUpdate(Statement.of(sql));
- System.out.printf("%d record inserted.\n", rowCount);
- return null;
- }
- }
- );
-
- }
- catch( Exception e ){
- System.out.println("Writing to DB failed : " + e.getMessage());
- }
- finally {
- spanner.close();
- }
- }
-
- public static void getMidnightExchange(long expirationTime){
- // Instantiates a client
- SpannerOptions options = SpannerOptions.newBuilder().setProjectId(projectId).build();
- Spanner spanner = options.getService();
- try{
- // Creates a database client
- DatabaseClient dbClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
-
- String sql = String.format("SELECT ExchangeRateData FROM MidnightExchangeRate where ExpirationTime = {}",
- expirationTime);
-
- ResultSet resultSet = dbClient.singleUse().executeQuery(Statement.of(sql));
-
- // TODO map the result set to exchange rate.
-
- }
- catch( Exception e ){
- System.out.println("Writing to DB failed : " + e.getMessage());
- }
- finally {
- spanner.close();
- }
- }
-
-
- public static void main(){
- // copy instance and db id from spanner website
- String projectId = "ert-public-test-1";
- String instanceId = "ert-spanner-instance";
- String databaseId = "ert_data";
- // Instantiates a client
- SpannerOptions options = SpannerOptions.newBuilder().setProjectId(projectId).build();
- Spanner spanner = options.getService();
-
-
- try{
- // Creates a database client
- DatabaseClient dbClient = spanner.getDatabaseClient(DatabaseId.of(projectId, instanceId, databaseId));
-
- dbClient.readWriteTransaction().run(
- new TransactionRunner.TransactionCallable() {
- @Override
- public Void run(TransactionContext transaction) throws Exception {
- String sql = "INSERT INTO ExchangeRate (ExpirationTime, ExchagneRateData) " +
- "values ('1567022400', '1,15,1567018800;1,14,1567022400')";
- long rowCount = transaction.executeUpdate(Statement.of(sql));
- System.out.printf("%d record inserted.\n", rowCount);
- return null;
- }
- }
- );
-
- }
- catch( Exception e ){
- System.out.println("Writing to DB failed : " + e.getMessage());
- }
- finally {
- spanner.close();
- }
- }
-}
diff --git a/src/main/java/com/hedera/exchange/database/ExchangeRateAWSRD.java b/src/main/java/com/hedera/exchange/database/QueryHelper.java
similarity index 76%
rename from src/main/java/com/hedera/exchange/database/ExchangeRateAWSRD.java
rename to src/main/java/com/hedera/exchange/database/QueryHelper.java
index 9d4cd65..a1287d8 100644
--- a/src/main/java/com/hedera/exchange/database/ExchangeRateAWSRD.java
+++ b/src/main/java/com/hedera/exchange/database/QueryHelper.java
@@ -53,6 +53,7 @@
*/
import com.hedera.exchange.ERTAddressBook;
+import com.hedera.exchange.Environment;
import com.hedera.exchange.ExchangeRate;
import com.hedera.exchange.exchanges.Exchange;
import org.apache.logging.log4j.LogManager;
@@ -61,45 +62,53 @@
import java.io.IOException;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import static com.hedera.exchange.ExchangeRateTool.env;
+import static com.hedera.exchange.database.DBParams.getEndpoint;
+import static com.hedera.exchange.database.DBParams.getGcpDataSource;
+import static com.hedera.exchange.database.DBParams.getPassword;
+import static com.hedera.exchange.database.DBParams.getUsername;
+
/**
- * This class implements the ExchangeDB interface using AWS RDS
+ * This class implements the ExchangeDB interface
* which species what APIs that we need to fetch/push data into the Database.
*
* If you foresee doing more of this mapping, I would recommend moving to JPA/Hibernate.
*
*/
-public class ExchangeRateAWSRD implements ExchangeDB {
-
- private static final Logger LOGGER = LogManager.getLogger(ExchangeRateAWSRD.class);
+public class QueryHelper implements ExchangeDB {
- private static final String LATEST_EXCHANGE_QUERY = "SELECT e1.expirationTime, e1.exchangeRateFile FROM exchange_rate AS e1 INNER JOIN (SELECT MAX(expirationTime) expirationTime FROM exchange_rate) AS e2 ON e1.expirationTime = e2.expirationTime LIMIT 1";
+ private static final Logger LOGGER = LogManager.getLogger(QueryHelper.class);
- private static final String LATEST_ADDRESSBOOK_QUERY = "SELECT e1.expirationTime, e1.addressBook FROM address_book AS e1 INNER JOIN (SELECT MAX(expirationTime) expirationTime FROM address_book) AS e2 ON e1.expirationTime = e2.expirationTime and networkName = ? LIMIT 1";
+ private static final String LATEST_EXCHANGE_QUERY = "SELECT e1.expiration_time, e1.exchange_rate_file FROM exchange_rate AS e1 INNER JOIN (SELECT MAX(expiration_time) expiration_time FROM exchange_rate) AS e2 ON e1.expiration_time = e2.expiration_time LIMIT 1";
- private static final String MIDNIGHT_EXCHANGE_QUERY = "SELECT e1.expirationTime, e1.exchangeRateFile FROM midnight_rate AS e1 INNER JOIN (SELECT MAX(expirationTime) expirationTime FROM midnight_rate) AS e2 ON e1.expirationTime = e2.expirationTime LIMIT 1";
+ private static final String LATEST_ADDRESS_BOOK_QUERY = "SELECT e1.expiration_time, e1.address_book FROM address_book AS e1 INNER JOIN (SELECT MAX(expiration_time) expiration_time FROM address_book) AS e2 ON e1.expiration_time = e2.expiration_time and network_name = ? LIMIT 1";
- private static final String LATEST_QUERIED_QUERY = "SELECT e1.expirationTime, e1.queriedrates FROM queried_rate AS e1 INNER JOIN (SELECT MAX(expirationTime) expirationTime FROM queried_rate) AS e2 ON e1.expirationTime = e2.expirationTime LIMIT 1";
+ private static final String MIDNIGHT_EXCHANGE_QUERY = "SELECT e1.expiration_time, e1.exchange_rate_file FROM midnight_rate AS e1 INNER JOIN (SELECT MAX(expiration_time) expiration_time FROM midnight_rate) AS e2 ON e1.expiration_time = e2.expiration_time LIMIT 1";
- private final AWSDBParams params;
+ private static final String LATEST_QUERIED_QUERY = "SELECT e1.expiration_time, e1.queried_rates FROM queried_rates AS e1 INNER JOIN (SELECT MAX(expiration_time) expiration_time FROM queried_rates) AS e2 ON e1.expiration_time = e2.expiration_time LIMIT 1";
- public ExchangeRateAWSRD(final AWSDBParams params) {
- this.params = params;
+ public QueryHelper() {
this.migrate();
}
private void migrate() {
- final Flyway flyway = Flyway.configure()
- .dataSource(this.params.getEndpoint(),
- this.params.getUsername(),
- this.params.getPassword())
- .baselineOnMigrate(true)
- .load();
+ final Flyway flyway;
+ if (env == Environment.AWS) {
+ flyway = Flyway.configure()
+ .dataSource(getEndpoint(), getUsername(), getPassword())
+ .baselineOnMigrate(true)
+ .load();
+ } else {
+ flyway = Flyway.configure()
+ .dataSource(getGcpDataSource())
+ .baselineOnMigrate(true)
+ .load();
+ }
flyway.migrate();
}
@@ -107,9 +116,9 @@ private void migrate() {
public ExchangeRate getMidnightExchangeRate(long expirationTime) throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get the midnight exchange rate from midnight rate table " +
"with nextExpiration time :{}", expirationTime);
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement prepStatement = conn.prepareStatement(
- "SELECT expirationTime, exchangeRateFile FROM midnight_rate where expirationTime = ?")){
+ "SELECT expiration_time, exchange_rate_file FROM midnight_rate where expiration_time = ?")){
prepStatement.setLong(1, expirationTime);
final ResultSet result = prepStatement.executeQuery();
if (result.next()) {
@@ -125,8 +134,8 @@ public ExchangeRate getMidnightExchangeRate(long expirationTime) throws SQLExcep
@Override
public ERTAddressBook getLatestERTAddressBook(String networkName) throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get latest ERTAddressBook from address_book table");
- try (final Connection conn = getConnection();
- final PreparedStatement statement = conn.prepareStatement(LATEST_ADDRESSBOOK_QUERY)) {
+ try (final Connection conn = DBParams.getConnection();
+ final PreparedStatement statement = conn.prepareStatement(LATEST_ADDRESS_BOOK_QUERY)) {
statement.setString(1, networkName);
LOGGER.info(Exchange.EXCHANGE_FILTER,"final query for addressbook : {}",
statement.toString());
@@ -147,9 +156,9 @@ public void pushERTAddressBook(long expirationTime, ERTAddressBook ertAddressBoo
String addressBook = ertAddressBook.toJson();
LOGGER.info(Exchange.EXCHANGE_FILTER, "push latest addressBook to address_book table : {}",
addressBook);
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement statement = conn.prepareStatement(
- "INSERT INTO address_book (expirationTime,addressBook,networkName) VALUES(?,?::JSON,?)")) {
+ "INSERT INTO address_book (expiration_time, address_book, network_name) VALUES(?,?::JSON,?)")) {
statement.setLong(1, expirationTime);
statement.setObject(2, addressBook);
statement.setString(3,networkName);
@@ -160,7 +169,7 @@ public void pushERTAddressBook(long expirationTime, ERTAddressBook ertAddressBoo
@Override
public ExchangeRate getLatestExchangeRate() throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get latest exchange rate from exchange rate table");
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final Statement statement = conn.createStatement();
final ResultSet result = statement.executeQuery(LATEST_EXCHANGE_QUERY)) {
if (result.next()) {
@@ -176,9 +185,9 @@ public ExchangeRate getLatestExchangeRate() throws SQLException, IOException {
public ExchangeRate getExchangeRate(long expirationTime) throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get the exchange rate from exchange rate table " +
"with nextExpiration time :{}", expirationTime);
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement prepStatement = conn.prepareStatement(
- "SELECT expirationTime, exchangeRateFile FROM exchange_rate where expirationTime = ?")){
+ "SELECT expiration_time, exchange_rate_file FROM exchange_rate where expiration_time = ?")){
prepStatement.setLong(1, expirationTime);
final ResultSet result = prepStatement.executeQuery();
if (result.next()) {
@@ -195,9 +204,9 @@ public ExchangeRate getExchangeRate(long expirationTime) throws SQLException, IO
public String getQueriedRate(long expirationTime) throws SQLException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get the queried rate from queried rate table " +
"with nextExpiration time :{}", expirationTime);
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement prepStatement = conn.prepareStatement(
- "SELECT expirationTime, queriedrates FROM queried_rate where expirationTime = ?")){
+ "SELECT expiration_time, queried_rates FROM queried_rates where expiration_time = ?")){
prepStatement.setLong(1, expirationTime);
final ResultSet result = prepStatement.executeQuery();
if (result.next()) {
@@ -213,7 +222,7 @@ public String getQueriedRate(long expirationTime) throws SQLException {
@Override
public ExchangeRate getLatestMidnightExchangeRate() throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get midnight exchange rate from midnight rate table");
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final Statement statement = conn.createStatement();
final ResultSet result = statement.executeQuery(MIDNIGHT_EXCHANGE_QUERY)) {
if (result.next()) {
@@ -228,7 +237,7 @@ public ExchangeRate getLatestMidnightExchangeRate() throws SQLException, IOExcep
@Override
public String getLatestQueriedRate() throws SQLException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "query to get the latest queried rate");
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final Statement statement = conn.createStatement();
final ResultSet result = statement.executeQuery(LATEST_QUERIED_QUERY)) {
if (result.next()) {
@@ -244,9 +253,9 @@ public String getLatestQueriedRate() throws SQLException {
public void pushExchangeRate(ExchangeRate exchangeRate) throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "push latest exchange rate to exchange rate table : {}",
exchangeRate.toJson());
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement statement = conn.prepareStatement(
- "INSERT INTO exchange_rate (expirationTime,exchangeRateFile) VALUES(?,?::JSON)")) {
+ "INSERT INTO exchange_rate (expiration_time, exchange_rate_file) VALUES(?,?::JSON)")) {
statement.setLong(1, exchangeRate.getNextExpirationTimeInSeconds());
statement.setObject(2, exchangeRate.toJson());
statement.executeUpdate();
@@ -257,9 +266,9 @@ public void pushExchangeRate(ExchangeRate exchangeRate) throws SQLException, IOE
public void pushMidnightRate(ExchangeRate exchangeRate) throws SQLException, IOException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "push the midnight exchange rate to midnight rate table : {}",
exchangeRate.toJson());
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement statement = conn.prepareStatement(
- "INSERT INTO midnight_rate (expirationTime,exchangeRateFile) VALUES(?,?::JSON)")) {
+ "INSERT INTO midnight_rate (expiration_time, exchange_rate_file) VALUES(?,?::JSON)")) {
statement.setLong(1, exchangeRate.getNextExpirationTimeInSeconds());
statement.setObject(2, exchangeRate.toJson());
statement.executeUpdate();
@@ -270,21 +279,13 @@ public void pushMidnightRate(ExchangeRate exchangeRate) throws SQLException, IOE
public void pushQueriedRate(long expirationTime, String queriedRate) throws SQLException {
LOGGER.info(Exchange.EXCHANGE_FILTER, "push the queried exchanges to queried rate table : {}:{}",
expirationTime, queriedRate);
- try (final Connection conn = getConnection();
+ try (final Connection conn = DBParams.getConnection();
final PreparedStatement statement = conn.prepareStatement(
- "INSERT INTO queried_rate (expirationTime,queriedrates) VALUES(?,?::JSON)")) {
+ "INSERT INTO queried_rates (expiration_time, queried_rates) VALUES(?,?::JSON)")) {
statement.setLong(1, expirationTime);
statement.setObject(2, queriedRate);
statement.executeUpdate();
}
}
- private Connection getConnection() throws SQLException {
- final String endpoint = this.params.getEndpoint();
- LOGGER.info(Exchange.EXCHANGE_FILTER, "Connecting to endpoint: {}", endpoint);
- return DriverManager.getConnection(endpoint,
- this.params.getUsername(),
- this.params.getPassword());
- }
-
}
diff --git a/src/main/resources/config.json.All b/src/main/resources/config.json.All
new file mode 100644
index 0000000..9157e9d
--- /dev/null
+++ b/src/main/resources/config.json.All
@@ -0,0 +1,76 @@
+{
+ "exchanges": {
+ "bitrex": "https://api.bittrex.com/api/v1.1/public/getmarketsummary?market=USD-HBAR",
+ "liquid": "https://api.liquid.com/products/741",
+ "coinbase": "https://api.coinbase.com/v2/exchange-rates?currency=HBAR",
+ "okcoin": "https://www.okcoin.com/api/spot/v3/instruments/HBAR-USD/ticker",
+ "binance": "https://api.binance.us/api/v3/ticker/24hr?symbol=HBARUSD",
+ "gate": "https://api.gateio.ws/api/v4/spot/tickers?currency_pair=HBAR_USDT",
+ "bitmart": "https://api-cloud.bitmart.com/contract/v1/tickers?contract_symbol=HBARUSDT",
+ "bittrue": "https://openapi.bitrue.com/api/v1/ticker/24hr?symbol=HBARUSDT",
+ "hitbit": "https://api.hitbtc.com/api/3/public/ticker/HBARUSDT",
+ "huobi" : "https://api.huobi.pro/market/detail?symbol=hbarusdt",
+ "upbit": "https://api.upbit.com/v1/ticker?markets=USD-HBAR",
+ "paybito": "https://stream.paybito.com:8443/SocketStream/api/get24hTicker?counter=HBAR&base=USD"
+ },
+ "defaultCentEquiv" : 360000,
+ "defaultHbarEquiv": 30000,
+ "frequencyInSeconds" : 3600,
+ "floorCentsPerHbar": 0,
+ "fileId": "0.0.112",
+ "maxTransactionFee": 10000000,
+ "exchangeRateAllowedPercentage": "25",
+ "operatorId": "0.0.57",
+ "Networks": {
+ "mainnet": {
+ "0.0.3": "35.237.200.180:50211",
+ "0.0.4": "35.186.191.247:50211",
+ "0.0.5": "35.192.2.25:50211",
+ "0.0.6": "35.199.161.108:50211"
+ },
+ "testnetstable": {
+ "0.0.3": "0.testnet.hedera.com:50211",
+ "0.0.4": "1.testnet.hedera.com:50211"
+ },
+ "previewNet": {
+ "0.0.3": "35.231.208.148:50211",
+ "0.0.4": "35.199.15.177:50211",
+ "0.0.5": "35.225.201.195:50211"
+ },
+ "integrationNet": {
+ "0.0.3": "34.74.191.8:50211",
+ "0.0.4": "35.245.150.69:50211",
+ "0.0.5": "34.70.193.123:50211"
+ },
+ "performanceNet": {
+ "0.0.3": "34.67.136.38:50211",
+ "0.0.6": "34.83.73.160:50211",
+ "0.0.7": "34.94.104.178:50211",
+ "0.0.8": "35.203.2.132:50211"
+ },
+ "performance2testNet": {
+ "0.0.3": "34.71.110.128:50211",
+ "0.0.4": "34.75.170.122:50211",
+ "0.0.5": "34.101.241.32:50211",
+ "0.0.6": "35.203.2.132:50211"
+ },
+ "stagingNetSmall": {
+ "0.0.3": "104.196.48.231:50211",
+ "0.0.8": "35.203.26.115:50211",
+ "0.0.9": "34.77.3.213:50211"
+ },
+ "stagingNetLarge": {
+ "0.0.3":"35.237.208.135:50211",
+ "0.0.4":"35.236.222.232:50211",
+ "0.0.5":"34.68.193.194:50211"
+ },
+ "devnetdevopstest": {
+ "0.0.3":"35.196.138.70:50211",
+ "0.0.4":"35.236.198.2:50211",
+ "0.0.5":"34.68.119.250:50211"
+ }
+ },
+ "payerAccount": "0.0.57",
+ "region": "us-central1",
+ "validationDelayInMilliseconds": 10000
+}
\ No newline at end of file
diff --git a/src/main/resources/config.json.devnetdevopstest b/src/main/resources/config.json.devnetdevopstest
new file mode 100644
index 0000000..2a9be26
--- /dev/null
+++ b/src/main/resources/config.json.devnetdevopstest
@@ -0,0 +1,34 @@
+{
+ "exchanges": {
+ "bitrex": "https://api.bittrex.com/api/v1.1/public/getmarketsummary?market=USD-HBAR",
+ "liquid": "https://api.liquid.com/products/741",
+ "coinbase": "https://api.coinbase.com/v2/exchange-rates?currency=HBAR",
+ "okcoin": "https://www.okcoin.com/api/spot/v3/instruments/HBAR-USD/ticker",
+ "binance": "https://api.binance.us/api/v3/ticker/24hr?symbol=HBARUSD",
+ "gate": "https://api.gateio.ws/api/v4/spot/tickers?currency_pair=HBAR_USDT",
+ "bitmart": "https://api-cloud.bitmart.com/contract/v1/tickers?contract_symbol=HBARUSDT",
+ "bittrue": "https://openapi.bitrue.com/api/v1/ticker/24hr?symbol=HBARUSDT",
+ "hitbit": "https://api.hitbtc.com/api/3/public/ticker/HBARUSDT",
+ "huobi" : "https://api.huobi.pro/market/detail?symbol=hbarusdt",
+ "upbit": "https://api.upbit.com/v1/ticker?markets=USD-HBAR",
+ "paybito": "https://stream.paybito.com:8443/SocketStream/api/get24hTicker?counter=HBAR&base=USD"
+ },
+ "defaultCentEquiv" : 360000,
+ "defaultHbarEquiv": 30000,
+ "frequencyInSeconds" : 3600,
+ "floorCentsPerHbar": 0,
+ "fileId": "0.0.112",
+ "maxTransactionFee": 10000000,
+ "exchangeRateAllowedPercentage": "25",
+ "operatorId": "0.0.57",
+ "Networks": {
+ "devnetdevopstest": {
+ "0.0.3":"35.196.138.70:50211",
+ "0.0.4":"35.236.198.2:50211",
+ "0.0.5":"34.68.119.250:50211"
+ }
+ },
+ "payerAccount": "0.0.57",
+ "region": "us-central1",
+ "validationDelayInMilliseconds": 10000
+}
\ No newline at end of file
diff --git a/src/main/resources/config.json.mainnet b/src/main/resources/config.json.mainnet
new file mode 100644
index 0000000..35e871a
--- /dev/null
+++ b/src/main/resources/config.json.mainnet
@@ -0,0 +1,35 @@
+{
+ "exchanges": {
+ "bitrex": "https://api.bittrex.com/api/v1.1/public/getmarketsummary?market=USD-HBAR",
+ "liquid": "https://api.liquid.com/products/741",
+ "coinbase": "https://api.coinbase.com/v2/exchange-rates?currency=HBAR",
+ "okcoin": "https://www.okcoin.com/api/spot/v3/instruments/HBAR-USD/ticker",
+ "binance": "https://api.binance.us/api/v3/ticker/24hr?symbol=HBARUSD",
+ "gate": "https://api.gateio.ws/api/v4/spot/tickers?currency_pair=HBAR_USDT",
+ "bitmart": "https://api-cloud.bitmart.com/contract/v1/tickers?contract_symbol=HBARUSDT",
+ "bittrue": "https://openapi.bitrue.com/api/v1/ticker/24hr?symbol=HBARUSDT",
+ "hitbit": "https://api.hitbtc.com/api/3/public/ticker/HBARUSDT",
+ "huobi" : "https://api.huobi.pro/market/detail?symbol=hbarusdt",
+ "upbit": "https://api.upbit.com/v1/ticker?markets=USD-HBAR",
+ "paybito": "https://stream.paybito.com:8443/SocketStream/api/get24hTicker?counter=HBAR&base=USD"
+ },
+ "defaultCentEquiv" : 360000,
+ "defaultHbarEquiv": 30000,
+ "frequencyInSeconds" : 3600,
+ "floorCentsPerHbar": 0,
+ "fileId": "0.0.112",
+ "maxTransactionFee": 10000000,
+ "exchangeRateAllowedPercentage": "25",
+ "operatorId": "0.0.57",
+ "Networks": {
+ "mainnet": {
+ "0.0.3": "35.237.200.180:50211",
+ "0.0.4": "35.186.191.247:50211",
+ "0.0.5": "35.192.2.25:50211",
+ "0.0.6": "35.199.161.108:50211"
+ }
+ },
+ "payerAccount": "0.0.57",
+ "region": "us-central1",
+ "validationDelayInMilliseconds": 10000
+}
\ No newline at end of file
diff --git a/src/main/resources/config.json.testnet b/src/main/resources/config.json.testnet
new file mode 100644
index 0000000..85901ce
--- /dev/null
+++ b/src/main/resources/config.json.testnet
@@ -0,0 +1,31 @@
+{
+ "exchanges": {
+ "bitrex": "https://api.bittrex.com/api/v1.1/public/getmarketsummary?market=USD-HBAR",
+ "liquid": "https://api.liquid.com/products/741",
+ "coinbase": "https://api.coinbase.com/v2/exchange-rates?currency=HBAR",
+ "okcoin": "https://www.okcoin.com/api/spot/v3/instruments/HBAR-USD/ticker",
+ "binance": "https://api.binance.us/api/v3/ticker/24hr?symbol=HBARUSD",
+ "gate": "https://api.gateio.ws/api/v4/spot/tickers?currency_pair=HBAR_USDT",
+ "bitmart": "https://api-cloud.bitmart.com/contract/v1/tickers?contract_symbol=HBARUSDT",
+ "bittrue": "https://openapi.bitrue.com/api/v1/ticker/24hr?symbol=HBARUSDT",
+ "hitbit": "https://api.hitbtc.com/api/3/public/ticker/HBARUSDT",
+ "huobi" : "https://api.huobi.pro/market/detail?symbol=hbarusdt"
+ },
+ "defaultCentEquiv" : 360000,
+ "defaultHbarEquiv": 30000,
+ "frequencyInSeconds" : 3600,
+ "floorCentsPerHbar": 0,
+ "fileId": "0.0.112",
+ "maxTransactionFee": 10000000,
+ "exchangeRateAllowedPercentage": "25",
+ "operatorId": "0.0.57",
+ "Networks": {
+ "publicTestNet": {
+ "0.0.3": "0.testnet.hedera.com:50211",
+ "0.0.4": "1.testnet.hedera.com:50211"
+ }
+ },
+ "payerAccount": "0.0.57",
+ "region": "us-central1",
+ "validationDelayInMilliseconds": 10000
+}
diff --git a/src/main/resources/configIntegration.json b/src/main/resources/configIntegration.json
index 101b4ab..5662a46 100644
--- a/src/main/resources/configIntegration.json
+++ b/src/main/resources/configIntegration.json
@@ -18,6 +18,12 @@
"Nodes": {
"0.0.3": "35.196.146.2:50211"
},
+ "Networks": {
+ "integrationNet": {
+ "0.0.4": "35.245.150.69:50211",
+ "0.0.5": "34.70.193.123:50211"
+ }
+ },
"payerAccount": "0.0.57"
}