All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.yandex.ydb.jdbc.settings.YdbProperties Maven / Gradle / Ivy
package com.yandex.ydb.jdbc.settings;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;
import com.google.common.net.HostAndPort;
import com.yandex.ydb.jdbc.exception.YdbConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.yandex.ydb.jdbc.YdbConst.JDBC_YDB_PREFIX;
public class YdbProperties {
private static final Logger LOGGER = LoggerFactory.getLogger(YdbProperties.class);
private static final String FILE_REF = "file:";
private static final String CLASSPATH_REF = "classpath:";
private static final String HOME_REF = "~";
private static final String FILE_HOME_REF = FILE_REF + HOME_REF;
private final YdbConnectionProperties connectionProperties;
private final YdbClientProperties clientProperties;
private final YdbOperationProperties operationProperties;
public YdbProperties(YdbConnectionProperties connectionProperties, YdbClientProperties clientProperties,
YdbOperationProperties operationProperties) {
this.connectionProperties = Objects.requireNonNull(connectionProperties);
this.clientProperties = Objects.requireNonNull(clientProperties);
this.operationProperties = Objects.requireNonNull(operationProperties);
}
public YdbConnectionProperties getConnectionProperties() {
return connectionProperties;
}
public YdbClientProperties getClientProperties() {
return clientProperties;
}
public YdbOperationProperties getOperationProperties() {
return operationProperties;
}
public DriverPropertyInfo[] toDriverProperties() {
List properties = new ArrayList<>();
connectionProperties.getParams().forEach((property, value) ->
properties.add(property.toDriverPropertyInfoFrom(value)));
clientProperties.getParams().forEach((property, value) ->
properties.add(property.toDriverPropertyInfoFrom(value)));
operationProperties.getParams().forEach((property, value) ->
properties.add(property.toDriverPropertyInfoFrom(value)));
return properties.toArray(new DriverPropertyInfo[0]);
}
//
public static boolean isYdb(String url) {
return url.startsWith(JDBC_YDB_PREFIX);
}
@SuppressWarnings("UnstableApiUsage")
public static YdbProperties from(String url, Properties origProperties) throws SQLException {
if (!isYdb(url)) {
throw new YdbConfigurationException("[" + url + "] is not a YDB URL, must starts from " + JDBC_YDB_PREFIX);
}
url = url.substring(JDBC_YDB_PREFIX.length());
String addressesUrl = getAddressesUrl(url);
url = url.substring(addressesUrl.length());
List addresses = getAddresses(addressesUrl);
Properties properties = withQuery(url, origProperties, getDatabase(url));
YdbConnectionProperties connectionProperties = new YdbConnectionProperties(addresses,
parseProperties(properties, YdbConnectionProperty.properties()));
YdbClientProperties ydbClientProperties = new YdbClientProperties(
parseProperties(properties, YdbClientProperty.properties()));
YdbOperationProperties ydbOperationProperties = new YdbOperationProperties(
parseProperties(properties, YdbOperationProperty.properties()));
return new YdbProperties(connectionProperties, ydbClientProperties, ydbOperationProperties);
}
private static String getAddressesUrl(String url) {
int databaseSep = url.indexOf('/');
int paramsSep = url.indexOf('?');
boolean nextDatabase = databaseSep >= 0;
boolean nextParams = paramsSep >= 0;
if (nextDatabase || nextParams) {
int pos;
if (nextDatabase && nextParams) {
pos = Math.min(databaseSep, paramsSep);
} else if (nextDatabase) {
pos = databaseSep;
} else {
pos = paramsSep;
}
return url.substring(0, pos);
} else {
return url;
}
}
@SuppressWarnings("UnstableApiUsage")
private static List getAddresses(String part) throws SQLException {
String[] addresses = part.split(",");
if (addresses.length == 0) {
throw invalidFormatException();
}
return Stream.of(addresses)
.map(HostAndPort::fromString)
.collect(Collectors.toList());
}
@Nullable
private static String getDatabase(String url) {
String database;
int paramsSeparator = url.indexOf('?');
if (paramsSeparator == 0) {
return null;
} else if (paramsSeparator > 0) {
database = url.substring(0, paramsSeparator);
} else {
database = url;
}
if (database.isEmpty() || database.equals("/")) {
return null;
}
return database;
}
private static Properties withQuery(String url, Properties defaults, String database) {
Properties properties = new Properties();
properties.putAll(defaults);
if (database != null) {
properties.setProperty(YdbConnectionProperty.DATABASE.getName(), database);
}
int paramsSeparator = url.indexOf('?');
if (paramsSeparator < 0) {
return properties;
}
String params = url.substring(paramsSeparator + 1);
if (params.isEmpty()) {
return properties;
}
String[] kv = params.split("&");
for (String keyValue : kv) {
String[] tokens = keyValue.split("=", 2);
if (tokens.length == 2) {
properties.put(tokens[0], tokens[1]);
} else {
LOGGER.error("Invalid property: {}", keyValue);
}
}
return properties;
}
private static > Map parseProperties(
Properties properties,
Collection knownProperties) throws SQLException {
Map result = new LinkedHashMap<>(knownProperties.size());
for (T property : knownProperties) {
String title = property.getName();
Object value = properties.get(title);
PropertyConverter> converter = property.getConverter();
ParsedProperty parsed;
if (value != null) {
if (value instanceof String) {
String stringValue = (String) value;
try {
parsed = new ParsedProperty(stringValue, converter.convert(stringValue));
} catch (SQLException e) {
throw new YdbConfigurationException("Unable to convert property " +
title + ": " + e.getMessage(), e);
}
} else {
if (property.getType().isAssignableFrom(value.getClass())) {
parsed = new ParsedProperty("", value);
} else {
throw new SQLException("Invalid object property " + title +
", must be " + property.getType() + ", got " + value.getClass());
}
}
} else {
String stringValue = property.getDefaultValue();
if (stringValue != null) {
try {
parsed = new ParsedProperty(stringValue, converter.convert(stringValue));
} catch (SQLException e) {
throw new YdbConfigurationException("Unable to convert property " +
title + ": " + e.getMessage(), e);
}
} else {
parsed = null;
}
}
result.put(property, parsed);
}
return Collections.unmodifiableMap(result);
}
private static SQLException invalidFormatException() {
return new SQLException("URL must be provided in form " + JDBC_YDB_PREFIX +
"host:port[/database][?param1=value1¶mN=valueN]");
}
//
public static String stringFileReference(String ref) throws YdbConfigurationException {
Optional urlOpt = YdbProperties.resolvePath(ref);
if (urlOpt.isPresent()) {
URL url = urlOpt.get();
try (Reader reader = new InputStreamReader(url.openStream())) {
return CharStreams.toString(reader).trim();
} catch (IOException e) {
throw new YdbConfigurationException("Unable to read resource from " + url, e);
}
} else {
return ref;
}
}
public static byte[] byteFileReference(String ref) throws YdbConfigurationException {
Optional urlOpt = YdbProperties.resolvePath(ref);
if (urlOpt.isPresent()) {
URL url = urlOpt.get();
try (InputStream stream = url.openStream()) {
return ByteStreams.toByteArray(stream);
} catch (IOException e) {
throw new YdbConfigurationException("Unable to read resource from " + url, e);
}
} else {
throw new YdbConfigurationException("Must be 'file:' or 'classpath:' reference");
}
}
static Optional resolvePath(String ref) throws YdbConfigurationException {
if (ref.startsWith(HOME_REF) || ref.startsWith(FILE_HOME_REF)) {
try {
String home = System.getProperty("user.home");
String fixedRef = ref.startsWith(HOME_REF)
? ref.substring(HOME_REF.length())
: ref.substring(FILE_HOME_REF.length());
return Optional.of(new URL(FILE_REF + home + fixedRef));
} catch (MalformedURLException e) {
throw new YdbConfigurationException("Unable to parse ref from home: " + ref, e);
}
} else if (ref.startsWith(FILE_REF)) {
try {
return Optional.of(new URL(ref));
} catch (MalformedURLException e) {
throw new YdbConfigurationException("Unable to parse ref as file: " + ref, e);
}
} else if (ref.startsWith(CLASSPATH_REF)) {
URL systemResource = ClassLoader.getSystemResource(ref.substring(CLASSPATH_REF.length()));
if (systemResource == null) {
throw new YdbConfigurationException("Unable to find classpath resource: " + ref);
}
return Optional.of(systemResource);
} else {
return Optional.empty();
}
}
}