Java tutorial
/* * Copyright 2014 the original author or 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 io.orchestrate.client; import com.fasterxml.jackson.databind.JsonNode; import lombok.NonNull; import org.glassfish.grizzly.http.HttpContent; import org.glassfish.grizzly.http.HttpRequestPacket; import org.glassfish.grizzly.http.HttpResponsePacket; import org.glassfish.grizzly.http.Method; import javax.annotation.Nullable; import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import static io.orchestrate.client.Preconditions.checkArgument; import static io.orchestrate.client.Preconditions.checkNotNegative; import static io.orchestrate.client.Preconditions.checkNotNullOrEmpty; /** * The resource for the KV list features in the Orchestrate API. */ public class KvListResource extends BaseResource { /** The collection for the request. */ private final String collection; /** The start of the key range to paginate from. */ private @Nullable String startKey; /** Include the specified "startKey" if it exists. */ private boolean inclusive; /** The number of KV objects to retrieve. */ private int limit; /** Whether to retrieve the values for the list of objects. */ private boolean withValues; KvListResource(final OrchestrateClient client, final JacksonMapper mapper, final String collection) { super(client, mapper); assert (collection != null); assert (collection.length() > 0); this.collection = collection; this.inclusive = false; this.limit = 10; this.withValues = true; } /** * Fetch a paginated, lexicographically ordered list of items contained in a * collection. * * <p>Usage:</p> * <pre> * {@code * KvList<String> objects = * client.listCollection("someCollection") * .limit(10) * .get(String.class) * .get(); * } * </pre> * * @param clazz Type information for marshalling objects at runtime. * @param <T> The type to deserialize the result of the request to. * @return The prepared get request. */ public <T> OrchestrateRequest<KvList<T>> get(final @NonNull Class<T> clazz) { checkArgument(!inclusive || startKey != null, "'inclusive' requires 'startKey' for request."); final String uri = client.uri(collection); String query = "limit=".concat(Integer.toString(limit)); query = query.concat("&values=").concat(Boolean.toString(withValues)); if (startKey != null) { final String keyName = (inclusive) ? "startKey" : "afterKey"; query = query.concat('&' + keyName + '=').concat(client.encode(startKey)); } final HttpContent packet = HttpRequestPacket.builder().method(Method.GET).uri(uri).query(query).build() .httpContentBuilder().build(); return new OrchestrateRequest<KvList<T>>(client, packet, new ResponseConverter<KvList<T>>() { @Override public KvList<T> from(final HttpContent response) throws IOException { final int status = ((HttpResponsePacket) response.getHttpHeader()).getStatus(); assert (status == 200); final JsonNode jsonNode = toJsonNode(response); final OrchestrateRequest<KvList<T>> next; if (jsonNode.has("next")) { final String page = jsonNode.get("next").asText(); final URI url = URI.create(page); final HttpContent packet = HttpRequestPacket.builder().method(Method.GET).uri(uri) .query(url.getQuery()).build().httpContentBuilder().build(); next = new OrchestrateRequest<KvList<T>>(client, packet, this, false); } else { next = null; } final int count = jsonNode.get("count").asInt(); final List<KvObject<T>> results = new ArrayList<KvObject<T>>(count); final Iterator<JsonNode> iter = jsonNode.get("results").elements(); while (iter.hasNext()) { results.add(toKvObject(iter.next(), clazz)); } return new KvList<T>(results, count, next); } }); } /** * Add the 'startKey' to the result set, equivalent to: * * <pre> * {@code * this.inclusive(Boolean.TRUE); * } * </pre> * * @return The KV list resource. * @see #inclusive(boolean) */ public KvListResource inclusive() { return inclusive(Boolean.TRUE); } /** * If {@code inclusive} is {@code true} the 'startKey' will be included in * the result set. * * @param inclusive Whether to include the 'startKey' in the result set. * @return The KV list resource. */ public KvListResource inclusive(final boolean inclusive) { this.inclusive = inclusive; return this; } /** * The number of results to return. * * @param limit The number of KV objects to retrieve. * @return The KV list resource. */ public KvListResource limit(final int limit) { this.limit = checkNotNegative(limit, "limit"); return this; } /** * The start of the key range to paginate from including the specified value * if it exists. * * @param startKey The start of the key range to paginate from. * @return The KV list resource. */ public KvListResource startKey(final String startKey) { this.startKey = checkNotNullOrEmpty(startKey, "startKey"); return this; } /** * If {@code withValues} is {@code true} then the KV objects being listed * will be retrieved with their values. Defaults to {@code true}. * * @param withValues The setting for whether to retrieve KV values. * @return The KV list resource. */ public KvListResource withValues(final boolean withValues) { this.withValues = withValues; return this; } }