Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

add dbkvs runtime password config #5365

Merged
merged 3 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@
import com.palantir.atlasdb.keyvalue.api.TableReference;
import com.palantir.atlasdb.keyvalue.api.TimestampSeriesProvider;
import com.palantir.atlasdb.spi.KeyValueServiceConfig;
import com.palantir.atlasdb.spi.KeyValueServiceRuntimeConfig;
import com.palantir.atlasdb.util.MetricsManager;
import com.palantir.refreshable.Refreshable;
import com.palantir.timestamp.ManagedTimestampService;
import java.util.Optional;

/**
* See {@link com.palantir.atlasdb.spi.AtlasDbFactory}. A {@link DbTimeLockFactory} is an extension of an
Expand All @@ -33,8 +36,21 @@
public interface DbTimeLockFactory {
String getType();

/**
* @deprecated Creating a DbKeyValueService with this method will not support live reloading the DB password. Use
* {@link #createRawKeyValueService(MetricsManager, KeyValueServiceConfig, Refreshable, LeaderConfig)} instead.
*/
@Deprecated
default KeyValueService createRawKeyValueService(
MetricsManager metricsManager, KeyValueServiceConfig config, LeaderConfig leaderConfig) {
return createRawKeyValueService(metricsManager, config, Refreshable.only(Optional.empty()), leaderConfig);
}

KeyValueService createRawKeyValueService(
MetricsManager metricsManager, KeyValueServiceConfig config, LeaderConfig leaderConfig);
MetricsManager metricManager,
KeyValueServiceConfig config,
Refreshable<Optional<KeyValueServiceRuntimeConfig>> runtimeConfig,
LeaderConfig leaderConfig);

ManagedTimestampService createManagedTimestampService(
KeyValueService rawKvs, DbTimestampCreationSetting dbTimestampCreationSetting, boolean initializeAsync);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,14 @@ public abstract class ConnectionConfig {

public abstract String getDbLogin();

public abstract MaskedValue getDbPassword();
/**
* If a runtime config is present, this does not need to be set and will not be used. A default value is provided
* so that the config will parse when this field is missing.
*/
@Value.Default
public MaskedValue getDbPassword() {
return ImmutableMaskedValue.of("");
}

public abstract String getUrl();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public KeyValueService createRawKeyValueService(
config instanceof DbKeyValueServiceConfig,
"DbAtlasDbFactory expects a configuration of type DbKeyValueServiceConfiguration, found %s",
config.getClass());
return ConnectionManagerAwareDbKvs.create((DbKeyValueServiceConfig) config, initializeAsync);
return ConnectionManagerAwareDbKvs.create((DbKeyValueServiceConfig) config, runtimeConfig, initializeAsync);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* (c) Copyright 2021 Palantir Technologies Inc. All rights reserved.
*
* 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.palantir.atlasdb.keyvalue.dbkvs;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.auto.service.AutoService;
import com.palantir.atlasdb.spi.KeyValueServiceRuntimeConfig;
import com.palantir.nexus.db.pool.config.MaskedValue;
import org.immutables.value.Value;

@AutoService(KeyValueServiceRuntimeConfig.class)
@JsonSerialize(as = ImmutableDbKeyValueServiceRuntimeConfig.class)
@JsonDeserialize(as = ImmutableDbKeyValueServiceRuntimeConfig.class)
@Value.Immutable
public abstract class DbKeyValueServiceRuntimeConfig implements KeyValueServiceRuntimeConfig {

@Override
public String type() {
return DbAtlasDbFactory.TYPE;
}

public abstract MaskedValue getDbPassword();
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.palantir.atlasdb.keyvalue.dbkvs.timestamp.MultiSequenceTimestampSeriesProvider;
import com.palantir.atlasdb.spi.AtlasDbFactory;
import com.palantir.atlasdb.spi.KeyValueServiceConfig;
import com.palantir.atlasdb.spi.KeyValueServiceRuntimeConfig;
import com.palantir.atlasdb.timestamp.DbTimeLockFactory;
import com.palantir.atlasdb.util.MetricsManager;
import com.palantir.refreshable.Refreshable;
Expand All @@ -51,11 +52,14 @@ public String getType() {

@Override
public KeyValueService createRawKeyValueService(
MetricsManager metricsManager, KeyValueServiceConfig config, LeaderConfig leaderConfig) {
MetricsManager metricsManager,
KeyValueServiceConfig config,
Refreshable<Optional<KeyValueServiceRuntimeConfig>> runtimeConfig,
LeaderConfig leaderConfig) {
return delegate.createRawKeyValueService(
metricsManager,
config,
Refreshable.only(Optional.empty()),
runtimeConfig,
Optional.of(leaderConfig),
Optional.empty(), // This refers to an AtlasDB namespace - we use the config to talk to the db
AtlasDbFactory.THROWING_FRESH_TIMESTAMP_SOURCE, // This is how we give out timestamps!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
import com.palantir.atlasdb.AtlasDbConstants;
import com.palantir.atlasdb.keyvalue.api.KeyValueService;
import com.palantir.atlasdb.keyvalue.dbkvs.DbKeyValueServiceConfig;
import com.palantir.atlasdb.keyvalue.dbkvs.DbKeyValueServiceRuntimeConfig;
import com.palantir.atlasdb.keyvalue.impl.ForwardingKeyValueService;
import com.palantir.atlasdb.spi.KeyValueServiceRuntimeConfig;
import com.palantir.nexus.db.monitoring.timer.SqlTimer;
import com.palantir.nexus.db.monitoring.timer.SqlTimers;
import com.palantir.nexus.db.pool.ConnectionManager;
Expand All @@ -29,7 +31,9 @@
import com.palantir.nexus.db.sql.SQL;
import com.palantir.nexus.db.sql.SqlConnection;
import com.palantir.nexus.db.sql.SqlConnectionHelper;
import com.palantir.refreshable.Refreshable;
import java.sql.Connection;
import java.util.Optional;
import java.util.function.Supplier;

// This class should be removed and replaced by DbKvs when InDbTimestampStore depends directly on DbKvs
Expand All @@ -38,18 +42,49 @@ public final class ConnectionManagerAwareDbKvs extends ForwardingKeyValueService
private final ConnectionManager connManager;
private final SqlConnectionSupplier sqlConnectionSupplier;

/**
* @deprecated This method does not support live reloading the DB password. Use
* {@link #create(DbKeyValueServiceConfig, Refreshable, boolean)} instead.
*/
@Deprecated
public static ConnectionManagerAwareDbKvs create(DbKeyValueServiceConfig config) {
return create(config, AtlasDbConstants.DEFAULT_INITIALIZE_ASYNC);
}

/**
* @deprecated This method does not support live reloading the DB password. Use
* {@link #create(DbKeyValueServiceConfig, Refreshable, boolean)} instead.
*/
@Deprecated
public static ConnectionManagerAwareDbKvs create(DbKeyValueServiceConfig config, boolean initializeAsync) {
return create(config, Refreshable.only(Optional.empty()), initializeAsync);
}

public static ConnectionManagerAwareDbKvs create(
DbKeyValueServiceConfig config,
Refreshable<Optional<KeyValueServiceRuntimeConfig>> runtimeConfig,
boolean initializeAsync) {
HikariCPConnectionManager connManager = new HikariCPConnectionManager(config.connection());
runtimeConfig.subscribe(newRuntimeConfig -> updateConnManagerConfig(connManager, config, newRuntimeConfig));
ReentrantManagedConnectionSupplier connSupplier = new ReentrantManagedConnectionSupplier(connManager);
SqlConnectionSupplier sqlConnSupplier = getSimpleTimedSqlConnectionSupplier(connSupplier);
return new ConnectionManagerAwareDbKvs(
DbKvs.create(config, sqlConnSupplier, initializeAsync), connManager, sqlConnSupplier);
}

private static void updateConnManagerConfig(
HikariCPConnectionManager connManager,
DbKeyValueServiceConfig config,
Optional<KeyValueServiceRuntimeConfig> runtimeConfig) {
if (runtimeConfig.isPresent() && runtimeConfig.get() instanceof DbKeyValueServiceRuntimeConfig) {
DbKeyValueServiceRuntimeConfig dbRuntimeConfig = (DbKeyValueServiceRuntimeConfig) runtimeConfig.get();
connManager.setPassword(dbRuntimeConfig.getDbPassword().unmasked());
} else {
// no runtime config (or wrong type), use the password from the install config
connManager.setPassword(config.connection().getDbPassword().unmasked());
}
}

private static SqlConnectionSupplier getSimpleTimedSqlConnectionSupplier(
ReentrantManagedConnectionSupplier connectionSupplier) {
Supplier<Connection> supplier = connectionSupplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@
import com.palantir.atlasdb.keyvalue.api.TimestampSeriesProvider;
import com.palantir.atlasdb.keyvalue.impl.InMemoryKeyValueService;
import com.palantir.atlasdb.spi.KeyValueServiceConfig;
import com.palantir.atlasdb.spi.KeyValueServiceRuntimeConfig;
import com.palantir.atlasdb.timestamp.DbTimeLockFactory;
import com.palantir.atlasdb.util.MetricsManager;
import com.palantir.refreshable.Refreshable;
import com.palantir.timestamp.InMemoryTimestampService;
import com.palantir.timestamp.ManagedTimestampService;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@AutoService(DbTimeLockFactory.class)
public class InMemoryDbTimeLockFactory implements DbTimeLockFactory {
Expand All @@ -43,7 +46,10 @@ public String getType() {

@Override
public KeyValueService createRawKeyValueService(
MetricsManager metricsManager, KeyValueServiceConfig config, LeaderConfig leaderConfig) {
MetricsManager metricManager,
KeyValueServiceConfig config,
Refreshable<Optional<KeyValueServiceRuntimeConfig>> runtimeConfig,
LeaderConfig leaderConfig) {
return new InMemoryKeyValueService(true);
}

Expand Down
6 changes: 6 additions & 0 deletions changelog/@unreleased/pr-5365.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type: improvement
improvement:
description: |-
Adds supports for live password changes for products that use the standard atlas install and runtime config. To take advantage of this products must add a runtime config for dbkvs (this appears in the same place as the cassandra runtime config would appear but has type "relational"). No behavior is changed when the new dbkvs runtime config is absent.
links:
- https://github.com/palantir/atlasdb/pull/5365