Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Resolves #1478: Support properties passing into FDBRecordStore, confi…
…gured by adopter. Firstly used for Lucene indexing's parameters for compression/encryption.
- Loading branch information
1 parent
96a8730
commit 93db7e3
Showing
13 changed files
with
529 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
...om/apple/foundationdb/record/provider/foundationdb/properties/RecordLayerPropertyKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* RecordLayerPropertyKey.java | ||
* | ||
* This source file is part of the FoundationDB open source project | ||
* | ||
* Copyright 2015-2021 Apple Inc. and the FoundationDB project authors | ||
* | ||
* 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.apple.foundationdb.record.provider.foundationdb.properties; | ||
|
||
import com.apple.foundationdb.annotation.API; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.Objects; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* A key for a property that adopter configures for Record Layer. | ||
* This is not supposed to be defined by adopter outside Record Layer. | ||
* The name, value type, and its default value are defined in this key, which are immutable. | ||
* Call {@link #buildValue(Supplier)} with a {@link Supplier} of the value to build a {@link RecordLayerPropertyValue}, | ||
* to override the value for the property, and then build a {@link RecordLayerPropertyStorage} with the new property value. | ||
* | ||
* @param <T> the type of the property's value | ||
*/ | ||
@API(API.Status.EXPERIMENTAL) | ||
public final class RecordLayerPropertyKey<T> { | ||
@Nonnull | ||
private final String name; | ||
@Nonnull | ||
private final T defaultValue; | ||
@Nonnull | ||
private final Class<T> type; | ||
|
||
private RecordLayerPropertyKey(@Nonnull final String name, @Nonnull T defaultValue, @Nonnull Class<T> type) { | ||
this.name = name; | ||
this.defaultValue = defaultValue; | ||
this.type = type; | ||
} | ||
|
||
/** | ||
* The name for each property needs to be unique and in a reverse FQDN format according to the package it is located. | ||
* | ||
* @return the name of this property | ||
*/ | ||
@Nonnull | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Nonnull | ||
public Class<T> getType() { | ||
return type; | ||
} | ||
|
||
@Nonnull | ||
public T getDefaultValue() { | ||
return defaultValue; | ||
} | ||
|
||
@Nonnull | ||
public RecordLayerPropertyValue<T> buildValue(@Nonnull Supplier<T> valueSupplier) { | ||
return new RecordLayerPropertyValue<>(this, valueSupplier); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object other) { | ||
if (other == null) { | ||
return false; | ||
} | ||
if (other.getClass() != this.getClass()) { | ||
return false; | ||
} | ||
RecordLayerPropertyKey<?> otherKey = (RecordLayerPropertyKey<?>) other; | ||
return this.name.equals(otherKey.name); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hashCode(name); | ||
} | ||
|
||
public static RecordLayerPropertyKey<Boolean> booleanPropertyKey(@Nonnull final String name, @Nonnull final boolean defaultValue) { | ||
return new RecordLayerPropertyKey<>(name, defaultValue, Boolean.class); | ||
} | ||
|
||
public static RecordLayerPropertyKey<String> stringPropertyKey(@Nonnull final String name, @Nonnull final String defaultValue) { | ||
return new RecordLayerPropertyKey<>(name, defaultValue, String.class); | ||
} | ||
|
||
public static RecordLayerPropertyKey<Integer> integerPropertyKey(@Nonnull final String name, @Nonnull final int defaultValue) { | ||
return new RecordLayerPropertyKey<>(name, defaultValue, Integer.class); | ||
} | ||
|
||
public static RecordLayerPropertyKey<Long> longPropertyKey(@Nonnull final String name, @Nonnull final long defaultValue) { | ||
return new RecordLayerPropertyKey<>(name, defaultValue, Long.class); | ||
} | ||
|
||
public static RecordLayerPropertyKey<Double> doublePropertyKey(@Nonnull final String name, @Nonnull final double defaultValue) { | ||
return new RecordLayerPropertyKey<>(name, defaultValue, Double.class); | ||
} | ||
} |
116 changes: 116 additions & 0 deletions
116
...pple/foundationdb/record/provider/foundationdb/properties/RecordLayerPropertyStorage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* RecordLayerPropertyStorage.java | ||
* | ||
* This source file is part of the FoundationDB open source project | ||
* | ||
* Copyright 2015-2021 Apple Inc. and the FoundationDB project authors | ||
* | ||
* 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.apple.foundationdb.record.provider.foundationdb.properties; | ||
|
||
import com.apple.foundationdb.annotation.API; | ||
import com.apple.foundationdb.record.RecordCoreException; | ||
import com.apple.foundationdb.record.logging.LogMessageKeys; | ||
import com.google.common.collect.ImmutableMap; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.Supplier; | ||
|
||
/** | ||
* Adopter can use this mapping of {@link RecordLayerPropertyKey}s to {@link RecordLayerPropertyValue}s to configure Record Layer parameters. | ||
* The instances of {@link RecordLayerPropertyKey} and how they are used are defined in Record Layer. | ||
* Adopters can populate {@link RecordLayerPropertyValue} and put them into this storage. | ||
*/ | ||
@API(API.Status.EXPERIMENTAL) | ||
public class RecordLayerPropertyStorage { | ||
private static final RecordLayerPropertyStorage EMPTY_PROPERTY_STORAGE = new RecordLayerPropertyStorage(ImmutableMap.of()); | ||
|
||
@Nonnull | ||
private final ImmutableMap<RecordLayerPropertyKey<?>, RecordLayerPropertyValue<?>> propertyMap; | ||
|
||
private RecordLayerPropertyStorage(@Nonnull ImmutableMap<RecordLayerPropertyKey<?>, RecordLayerPropertyValue<?>> propertyMap) { | ||
this.propertyMap = propertyMap; | ||
} | ||
|
||
@Nonnull | ||
public ImmutableMap<RecordLayerPropertyKey<?>, RecordLayerPropertyValue<?>> getPropertyMap() { | ||
return propertyMap; | ||
} | ||
|
||
@Nonnull | ||
public <T> T getPropertyValue(@Nonnull RecordLayerPropertyKey<T> propertyKey) { | ||
if (propertyMap.containsKey(propertyKey)) { | ||
Object value = propertyMap.get(propertyKey).getValue(); | ||
try { | ||
return propertyKey.getType().cast(value); | ||
} catch (ClassCastException ex) { | ||
throw new RecordCoreException("Invalid type for record context property", ex) | ||
.addLogInfo(LogMessageKeys.PROPERTY_NAME, propertyKey.getName(), | ||
LogMessageKeys.PROPERTY_TYPE, value.getClass().getName()); | ||
} | ||
} else { | ||
return propertyKey.getDefaultValue(); | ||
} | ||
} | ||
|
||
@Nonnull | ||
public Builder toBuilder() { | ||
return new Builder(propertyMap); | ||
} | ||
|
||
public static Builder newBuilder() { | ||
return new Builder(); | ||
} | ||
|
||
public static RecordLayerPropertyStorage getEmptyInstance() { | ||
return EMPTY_PROPERTY_STORAGE; | ||
} | ||
|
||
public static class Builder { | ||
private final Map<RecordLayerPropertyKey<?>, RecordLayerPropertyValue<?>> propertyMap; | ||
|
||
private Builder() { | ||
this.propertyMap = new HashMap<>(); | ||
} | ||
|
||
private Builder(ImmutableMap<RecordLayerPropertyKey<?>, RecordLayerPropertyValue<?>> properties) { | ||
this.propertyMap = new HashMap<>(properties); | ||
} | ||
|
||
public <T> Builder addProp(@Nonnull RecordLayerPropertyValue<T> propValue) { | ||
if (this.propertyMap.putIfAbsent(propValue.getKey(), propValue) != null) { | ||
throw new RecordCoreException("Duplicate property name is added") | ||
.addLogInfo(LogMessageKeys.PROPERTY_NAME, propValue.getKey().getName()); | ||
} | ||
return this; | ||
} | ||
|
||
public <T> Builder addProp(@Nonnull RecordLayerPropertyKey<T> propKey, @Nonnull Supplier<T> valueSupplier) { | ||
final RecordLayerPropertyValue<T> propValue = propKey.buildValue(valueSupplier); | ||
return this.addProp(propValue); | ||
} | ||
|
||
public <T> Builder addProp(@Nonnull RecordLayerPropertyKey<T> propKey, @Nonnull T value) { | ||
final RecordLayerPropertyValue<T> propValue = propKey.buildValue(() -> value); | ||
return this.addProp(propValue); | ||
} | ||
|
||
public RecordLayerPropertyStorage build() { | ||
return new RecordLayerPropertyStorage(ImmutableMap.copyOf(propertyMap)); | ||
} | ||
} | ||
} |
Oops, something went wrong.