com.scalar.dl.client.config.ClientConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scalardl-java-client-sdk Show documentation
Show all versions of scalardl-java-client-sdk Show documentation
A client-side Java library to interact with Scalar DL network.
/*
* This file is part of the Scalar DL client SDK.
* Copyright (c) 2019 Scalar, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* You can be released from the requirements of the license by purchasing
* a commercial license. For more information, please contact Scalar, Inc.
*/
package com.scalar.dl.client.config;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Splitter;
import com.scalar.dl.ledger.config.TargetConfig;
import com.scalar.dl.ledger.util.PropertiesUtil;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@Immutable
@SuppressFBWarnings("JCIP_FIELD_ISNT_FINAL_IN_IMMUTABLE_CLASS")
public class ClientConfig {
private static final String PREFIX = "scalar.dl.client.";
/**
* Optional. A hostname or an IP address of the server ("localhost" by default). It assumes that
* there is a single endpoint that is given by DNS or a load balancer.
*/
public static final String SERVER_HOST = PREFIX + "server.host";
/** Optional. A port number of the server (50051 by default). */
public static final String SERVER_PORT = PREFIX + "server.port";
/** Optional. A port number of the server for privileged services (50052 by default). */
public static final String SERVER_PRIVILEGED_PORT = PREFIX + "server.privileged_port";
/**
* Required. The holder ID of a certificate. It must be configured for each private key and unique
* in the system.
*/
public static final String CERT_HOLDER_ID = PREFIX + "cert_holder_id";
/**
* Optional. The version of the certificate (1 by default). Use another bigger integer if you need
* to change your private key.
*/
public static final String CERT_VERSION = PREFIX + "cert_version";
/** Required. The path of the certificate file in PEM format. */
public static final String CERT_PATH = PREFIX + "cert_path";
/** Required if cert_path is empty. PEM-encoded certificate data. */
public static final String CERT_PEM = PREFIX + "cert_pem";
/** Required. The path of a corresponding private key file in PEM format to the certificate. */
public static final String PRIVATE_KEY_PATH = PREFIX + "private_key_path";
/** Required if private_key_path is empty. PEM-encoded private key data. */
public static final String PRIVATE_KEY_PEM = PREFIX + "private_key_pem";
/** Optional. A flag to enable TLS communication for Ledger (false by default). */
public static final String TLS_ENABLED = PREFIX + "tls.enabled";
/**
* Optional. A custom CA root certificate (file path) for TLS communication for Ledger. If the
* issuing certificate authority is known to the client, it can be empty.
*/
public static final String TLS_CA_ROOT_CERT_PATH = PREFIX + "tls.ca_root_cert_path";
/**
* Optional. A custom CA root certificate (PEM data) for TLS communication for Ledger. If the
* issuing certificate authority is known to the client, it can be empty.
*/
public static final String TLS_CA_ROOT_CERT_PEM = PREFIX + "tls.ca_root_cert_pem";
/**
* Optional. An authorization credential for Ledger. (e.g. authorization: Bearer token) If this is
* given, clients will add "authorization: [credential]" http/2 header.
*/
public static final String AUTHORIZATION_CREDENTIAL = PREFIX + "authorization.credential";
/**
* Optional. A client mode. CLIENT OR INTERMEDIARY. CLIENT by default. In INTERMEDIARY mode, this
* client receives a signed serialized request from another client, and sends it to a server.
*/
public static final String MODE = PREFIX + "mode";
/**
* Experimental. Proxy server. Proxy feature is deprecated and will be removed in release 4.0.0.
*/
@Deprecated public static final String PROXY_SERVER = PREFIX + "proxy.server";
/** Optional. A flag to enable auditor (false by default). */
public static final String AUDITOR_ENABLED = PREFIX + "auditor.enabled";
/**
* Optional. A hostname or an IP address of the auditor ("localhost" by default). It assumes that
* there is a single endpoint that is given by DNS or a load balancer.
*/
public static final String AUDITOR_HOST = PREFIX + "auditor.host";
/** Optional. A port number of the auditor (40051 by default). */
public static final String AUDITOR_PORT = PREFIX + "auditor.port";
/** Optional. A port number of the auditor for privileged services (40052 by default). */
public static final String AUDITOR_PRIVILEGED_PORT = PREFIX + "auditor.privileged_port";
/** Optional. A flag to enable TLS communication for Auditor (false by default). */
public static final String AUDITOR_TLS_ENABLED = PREFIX + "auditor.tls.enabled";
/**
* Optional. A custom CA root certificate (file path) for TLS communication for Auditor. If the
* issuing certificate authority is known to the client, it can be empty.
*/
public static final String AUDITOR_TLS_CA_ROOT_CERT_PATH =
PREFIX + "auditor.tls.ca_root_cert_path";
/**
* Optional. A custom CA root certificate (PEM data) for TLS communication for Auditor. If the
* issuing certificate authority is known to the client, it can be empty.
*/
public static final String AUDITOR_TLS_CA_ROOT_CERT_PEM = PREFIX + "auditor.tls.ca_root_cert_pem";
/**
* Optional. An authorization credential for Auditor. (e.g. authorization: Bearer token) If this
* is given, clients will add "authorization: [credential]" http/2 header.
*/
public static final String AUDITOR_AUTHORIZATION_CREDENTIAL =
PREFIX + "auditor.authorization.credential";
/**
* Optional. The ID of ValidateLedger contract ("validate-ledger" by default). It is used for the
* linearizable validation.
*/
public static final String AUDITOR_LINEARIZABLE_VALIDATION_CONTRACT_ID =
PREFIX + "auditor.linearizable_validation.contract_id";
static final String DEFAULT_SERVER_HOST = "localhost";
static final int DEFAULT_SERVER_PORT = 50051;
static final int DEFAULT_SERVER_PRIVILEGED_PORT = 50052;
static final int DEFAULT_CERT_VERSION = 1;
static final boolean DEFAULT_TLS_ENABLED = false;
private final Properties props;
private String serverHost = DEFAULT_SERVER_HOST;
private int serverPort = DEFAULT_SERVER_PORT;
private int serverPrivilegedPort = DEFAULT_SERVER_PRIVILEGED_PORT;
private String certHolderId;
private int certVersion = DEFAULT_CERT_VERSION;
private String cert;
private String privateKey;
private boolean isTlsEnabled = DEFAULT_TLS_ENABLED;
private String tlsCaRootCert;
private String authorizationCredential;
private ClientMode clientMode = ClientMode.CLIENT;
private Server proxyServer;
private boolean isAuditorEnabled = false;
private String auditorHost = "localhost";
private int auditorPort = 40051;
private int auditorPrivilegedPort = 40052;
private boolean isAuditorTlsEnabled = false;
private String auditorTlsCaRootCert;
private String auditorAuthorizationCredential;
private String auditorLinearizableValidationContractId = "validate-ledger";
private IdentityConfig identityConfig;
private TargetConfig ledgerTargetConfig;
private TargetConfig auditorTargetConfig;
public ClientConfig(File propertiesFile) throws IOException {
try (FileInputStream stream = new FileInputStream(propertiesFile)) {
props = new Properties();
props.load(stream);
}
load();
}
public ClientConfig(InputStream stream) throws IOException {
props = new Properties();
props.load(stream);
load();
}
public ClientConfig(Properties properties) throws IOException {
props = new Properties();
props.putAll(properties);
load();
}
public IdentityConfig getIdentityConfig() {
return identityConfig;
}
@Nonnull
public TargetConfig getLedgerTargetConfig() {
return ledgerTargetConfig;
}
@Nullable
public TargetConfig getAuditorTargetConfig() {
return auditorTargetConfig;
}
public ClientMode getClientMode() {
return clientMode;
}
/** Proxy feature is deprecated and will be removed in release 4.0.0. */
@Deprecated
public Server getProxyServer() {
return proxyServer;
}
public boolean isAuditorEnabled() {
return isAuditorEnabled;
}
public String getAuditorLinearizableValidationContractId() {
return auditorLinearizableValidationContractId;
}
private void load() {
if (PropertiesUtil.isNonEmpty(props, SERVER_HOST)) {
serverHost = props.getProperty(SERVER_HOST);
}
if (PropertiesUtil.isNonEmpty(props, SERVER_PORT)) {
serverPort = Integer.parseInt(props.getProperty(SERVER_PORT));
}
if (PropertiesUtil.isNonEmpty(props, SERVER_PRIVILEGED_PORT)) {
serverPrivilegedPort = Integer.parseInt(props.getProperty(SERVER_PRIVILEGED_PORT));
}
if (PropertiesUtil.isNonEmpty(props, MODE)) {
clientMode = ClientMode.valueOf(props.getProperty(MODE));
}
if (clientMode.equals(ClientMode.CLIENT)) {
checkArgument(
PropertiesUtil.isNonEmpty(props, CERT_HOLDER_ID),
CERT_HOLDER_ID + " is missing but required.");
certHolderId = props.getProperty(CERT_HOLDER_ID);
if (PropertiesUtil.isNonEmpty(props, CERT_VERSION)) {
certVersion = Integer.parseInt(props.getProperty(CERT_VERSION));
}
cert = PropertiesUtil.readFromStringOrFile(props, CERT_PEM, CERT_PATH);
checkArgument(cert != null, "either " + CERT_PEM + " or " + CERT_PATH + " is required.");
privateKey = PropertiesUtil.readFromStringOrFile(props, PRIVATE_KEY_PEM, PRIVATE_KEY_PATH);
checkArgument(
privateKey != null,
"either " + PRIVATE_KEY_PEM + " or " + PRIVATE_KEY_PATH + " is required.");
}
if (PropertiesUtil.isNonEmpty(props, TLS_ENABLED)) {
isTlsEnabled = Boolean.parseBoolean(props.getProperty(TLS_ENABLED));
}
tlsCaRootCert =
PropertiesUtil.readFromStringOrFile(props, TLS_CA_ROOT_CERT_PEM, TLS_CA_ROOT_CERT_PATH);
authorizationCredential = props.getProperty(AUTHORIZATION_CREDENTIAL);
if (PropertiesUtil.isNonEmpty(props, PROXY_SERVER)) {
proxyServer = parseServers(props.getProperty(PROXY_SERVER)).get(0);
}
if (PropertiesUtil.isNonEmpty(props, AUDITOR_ENABLED)) {
isAuditorEnabled = Boolean.parseBoolean(props.getProperty(AUDITOR_ENABLED));
}
if (isAuditorEnabled) {
if (PropertiesUtil.isNonEmpty(props, AUDITOR_HOST)) {
auditorHost = props.getProperty(AUDITOR_HOST);
}
if (PropertiesUtil.isNonEmpty(props, AUDITOR_PORT)) {
auditorPort = Integer.parseInt(props.getProperty(AUDITOR_PORT));
}
if (PropertiesUtil.isNonEmpty(props, AUDITOR_PRIVILEGED_PORT)) {
auditorPrivilegedPort = Integer.parseInt(props.getProperty(AUDITOR_PRIVILEGED_PORT));
}
if (PropertiesUtil.isNonEmpty(props, AUDITOR_TLS_ENABLED)) {
isAuditorTlsEnabled = Boolean.parseBoolean(props.getProperty(AUDITOR_TLS_ENABLED));
}
auditorTlsCaRootCert =
PropertiesUtil.readFromStringOrFile(
props, AUDITOR_TLS_CA_ROOT_CERT_PEM, AUDITOR_TLS_CA_ROOT_CERT_PATH);
auditorAuthorizationCredential = props.getProperty(AUDITOR_AUTHORIZATION_CREDENTIAL);
if (PropertiesUtil.isNonEmpty(props, AUDITOR_LINEARIZABLE_VALIDATION_CONTRACT_ID)) {
auditorLinearizableValidationContractId =
props.getProperty(AUDITOR_LINEARIZABLE_VALIDATION_CONTRACT_ID);
}
}
identityConfig = createIdentityConfig();
ledgerTargetConfig = createLedgerTargetConfig();
auditorTargetConfig = createAuditorTargetConfig();
}
@Nonnull
private IdentityConfig createIdentityConfig() {
return IdentityConfig.newBuilder()
.certHolderId(certHolderId)
.certVersion(certVersion)
.cert(cert)
.privateKey(privateKey)
.build();
}
@Nonnull
private TargetConfig createLedgerTargetConfig() {
return TargetConfig.newBuilder()
.host(serverHost)
.port(serverPort)
.privilegedPort(serverPrivilegedPort)
.tlsEnabled(isTlsEnabled)
.tlsCaRootCert(tlsCaRootCert)
.authorizationCredential(authorizationCredential)
.build();
}
@Nullable
private TargetConfig createAuditorTargetConfig() {
if (!isAuditorEnabled) {
return null;
}
return TargetConfig.newBuilder()
.host(auditorHost)
.port(auditorPort)
.privilegedPort(auditorPrivilegedPort)
.tlsEnabled(isAuditorTlsEnabled)
.tlsCaRootCert(auditorTlsCaRootCert)
.authorizationCredential(auditorAuthorizationCredential)
.build();
}
private List parseServers(String line) {
List list = new ArrayList<>();
for (String item : Splitter.on(',').split(line)) {
List elements = Splitter.on(':').splitToList(item);
list.add(new Server(elements.get(0), Integer.parseInt(elements.get(1))));
}
return list;
}
public static class Server {
private final String host;
private final int port;
public Server(String host, int port) {
this.host = host;
this.port = port;
}
public String getHost() {
return host;
}
public int getPort() {
return port;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy