Skip to content
This repository has been archived by the owner on Jul 27, 2023. It is now read-only.

Add get methods to get configuration values wrapped in consulResponse… #245

Merged
merged 3 commits into from
Jul 1, 2017
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.orbitz.consul</groupId>
<artifactId>consul-client</artifactId>
<packaging>jar</packaging>
<version>0.15.0</version>
<version>0.16.0</version>
<name>consul-client</name>
<url>http://maven.apache.org</url>
<description>Consul Client for Java</description>
Expand Down
76 changes: 75 additions & 1 deletion src/main/java/com/orbitz/consul/KeyValueClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ public Optional<Value> getValue(String key) {
return getValue(key, QueryOptions.BLANK);
}

/**
* Retrieves a {@link com.orbitz.consul.model.ConsulResponse} with the
* {@link com.orbitz.consul.model.kv.Value} for a spefici key from the
* key/value store
* @param key The key to retrieve
* @return An {@link Optional} containing the {@link ConsulResponse} or {@link Optional#absent()}
*/
public Optional<ConsulResponse<Value>> getConsulResponseWithValue(String key) {
return getConsulResponseWithValue(key, QueryOptions.BLANK);
}

/**
* Retrieves a {@link com.orbitz.consul.model.kv.Value} for a specific key
* from the key/value store.
Expand All @@ -94,6 +105,36 @@ public Optional<Value> getValue(String key, QueryOptions queryOptions) {
return Optional.absent();
}

/**
* Returns a {@link ConsulResponse<Value>} for a specific key from the kv store.
* Contains the consul response headers along with the configuration value.
*
* GET /v1/kv/{key}
*
* @param key The key to retrieve.
* @param queryOptions The query options.
* @return An {@link Optional} containing the ConsulResponse or {@link Optional#absent()}
*/
public Optional<ConsulResponse<Value>> getConsulResponseWithValue(String key, QueryOptions queryOptions) {
try {
ConsulResponse<List<Value>> consulResponse =
extractConsulResponse(api.getValue(trimLeadingSlash(key), queryOptions.toQuery()), NOT_FOUND_404);
Optional<Value> consulValue = getSingleValue(consulResponse.getResponse());
if (consulValue.isPresent()) {
ConsulResponse<Value> result =
new ConsulResponse<>(consulValue.get(), consulResponse.getLastContact(),
consulResponse.isKnownLeader(), consulResponse.getIndex());
return Optional.of(result);
}
} catch (ConsulException ignored) {
if (ignored.getCode() != NOT_FOUND_404) {
throw ignored;
}
}

return Optional.absent();
}

/**
* Asynchronously retrieves a {@link com.orbitz.consul.model.kv.Value} for a specific key
* from the key/value store.
Expand Down Expand Up @@ -123,7 +164,7 @@ public void onFailure(Throwable throwable) {
extractConsulResponse(api.getValue(trimLeadingSlash(key), queryOptions.toQuery()), wrapper, NOT_FOUND_404);
}

private Optional<Value> getSingleValue(List<Value> values){
private Optional<Value> getSingleValue(List<Value> values) {
return values != null && values.size() != 0 ? Optional.of(values.get(0)) : Optional.<Value>absent();
}

Expand All @@ -140,6 +181,20 @@ public List<Value> getValues(String key) {
return getValues(key, QueryOptions.BLANK);
}

/**
* Retrieves a {@link ConsulResponse} with a list of {@link Value} objects along with
* consul response headers for a specific key from the key/value store.
*
* GET /v1/kv/{key}?recurse
*
* @param key The key to retrieve.
* @return A {@link ConsulResponse} with a list of zero to many {@link Value} objects and
* consul response headers.
*/
public ConsulResponse<List<Value>> getConsulResponseWithValues(String key) {
return getConsulResponseWithValues(key, QueryOptions.BLANK);
}

/**
* Retrieves a list of {@link com.orbitz.consul.model.kv.Value} objects for a specific key
* from the key/value store.
Expand All @@ -160,6 +215,25 @@ public List<Value> getValues(String key, QueryOptions queryOptions) {
return result == null ? Collections.<Value>emptyList() : result;
}

/**
* Retrieves a {@link ConsulResponse} with a list of {@link Value} objects along with
* consul response headers for a specific key from the key/value store.
*
* GET /v1/kv/{key}?recurse
*
* @param key The key to retrieve.
* @param queryOptions The query options to use.
* @return A {@link ConsulResponse} with a list of zero to many {@link Value} objects and
* consul response headers.
*/
public ConsulResponse<List<Value>> getConsulResponseWithValues(String key, QueryOptions queryOptions) {
Map<String, Object> query = queryOptions.toQuery();

query.put("recursive", "true");

return extractConsulResponse(api.getValue(trimLeadingSlash(key), query), NOT_FOUND_404);
}

/**
* Asynchronously retrieves a list of {@link com.orbitz.consul.model.kv.Value} objects for a specific key
* from the key/value store.
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/orbitz/consul/cache/ConsulCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;

import static com.google.common.base.Preconditions.checkArgument;
Expand All @@ -47,6 +49,8 @@ enum State {latent, starting, started, stopped }
private static final long BACKOFF_DELAY_QTY_IN_MS = getBackOffDelayInMs(System.getProperties());

private final AtomicReference<BigInteger> latestIndex = new AtomicReference<BigInteger>(null);
private final AtomicLong lastContact = new AtomicLong();
private final AtomicBoolean isKnownLeader = new AtomicBoolean();
private final AtomicReference<ImmutableMap<K, V>> lastResponse = new AtomicReference<ImmutableMap<K, V>>(null);
private final AtomicReference<State> state = new AtomicReference<State>(State.latent);
private final CountDownLatch initLatch = new CountDownLatch(1);
Expand Down Expand Up @@ -82,6 +86,9 @@ public void onComplete(ConsulResponse<List<V>> consulResponse) {
if (changed) {
// changes
lastResponse.set(full);
// metadata changes
lastContact.set(consulResponse.getLastContact());
isKnownLeader.set(consulResponse.isKnownLeader());
}

if (changed) {
Expand Down Expand Up @@ -164,12 +171,15 @@ public ImmutableMap<K, V> getMap() {
return lastResponse.get();
}

public ConsulResponse<ImmutableMap<K,V>> getMapWithMetadata() {
return new ConsulResponse<>(lastResponse.get(), lastContact.get(), isKnownLeader.get(), latestIndex.get());
}

@VisibleForTesting
ImmutableMap<K, V> convertToMap(final ConsulResponse<List<V>> response) {
if (response == null || response.getResponse() == null || response.getResponse().isEmpty()) {
return ImmutableMap.of();
}

final ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
final Set<K> keySet = new HashSet<>();
for (final V v : response.getResponse()) {
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/com/orbitz/consul/KeyValueTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,38 @@ public void onFailure(Throwable throwable) {
assertTrue(success.get());
}

@Test
public void testGetConsulResponseWithValue() {
KeyValueClient keyValueClient = client.keyValueClient();
String key = UUID.randomUUID().toString();
String value = UUID.randomUUID().toString();
keyValueClient.putValue(key, value);

Optional<ConsulResponse<Value>> response = keyValueClient.getConsulResponseWithValue(key);

keyValueClient.deleteKey(key);

assertTrue(response.get().getResponse().getKey().equals(key));
assertTrue(response.get().getResponse().getValue().isPresent());
assertNotNull(response.get().getIndex());

}

@Test
public void testGetConsulResponseWithValues() {
KeyValueClient keyValueClient = client.keyValueClient();
String key = UUID.randomUUID().toString();
String value = UUID.randomUUID().toString();
keyValueClient.putValue(key, value);

ConsulResponse<List<Value>> response = keyValueClient.getConsulResponseWithValues(key);

keyValueClient.deleteKey(key);

assertTrue(!response.getResponse().isEmpty());
assertNotNull(response.getIndex());
}

@Test
public void testGetValueNotFoundAsync() throws InterruptedException {
KeyValueClient keyValueClient = client.keyValueClient();
Expand Down