All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.orchestrate.client.EventResource Maven / Gradle / Ivy

Go to download

A high performance, asynchronous Java client to query the Orchestrate.io service.

The newest version!
/*
 * 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.*;
import org.glassfish.grizzly.http.util.Header;
import org.glassfish.grizzly.memory.ByteBufferWrapper;

import javax.annotation.Nullable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static io.orchestrate.client.Preconditions.*;

/**
 * The resource for the event features in the Orchestrate API.
 */
public class EventResource extends BaseResource {

    /** The collection for the request. */
    private final String collection;
    /** The key for the request. */
    private final String key;
    /** The type of events to get. */
    private String type;
    /** The timestamp to get events from. */
    private Long start;
    /** The timestamp to get events up to. */
    private Long end;
    /** The number of KV objects to retrieve. */
    private int limit;
    /** The fully-qualified names of fields to select when filtering the result JSON */
    private String withFields;
    /** The fully-qualified names of fields to reject when filtering the result JSON */
    private String withoutFields;

    private Long timestamp;

    EventResource(final OrchestrateClient client,
                  final JacksonMapper mapper,
                  final String collection,
                  final String key) {
        super(client, mapper);
        assert (collection != null);
        assert (collection.length() > 0);
        assert (key != null);
        assert (key.length() > 0);

        this.collection = collection;
        this.key = key;
        this.start = null;
        this.end = null;
        this.limit = 10;
        this.withFields = null;
        this.withoutFields = null;
    }

    /**
     * Add an event to a key in the Orchestrate service as part of a bulk operation.
     *
     * @param value The object to store as the event.
     * @return The bulk operation
     *
     * @see #create(Object)
     * @see Client#bulk()
     */
    public BulkOperation bulkCreate(final @NonNull Object value) {
        return BulkOperation.forEvent(this.collection, this.key, this.type, this.timestamp, value);
    }

    /**
     * Fetch events for a key in the Orchestrate service.
     *
     * 

Usage:

*
     * {@code
     * EventList events =
     *         client.event("someCollection", "someKey")
     *               .type("eventType")
     *               .get(DomainObject.class)
     *               .get();
     * }
     * 
* * @param clazz Type information for marshalling objects at runtime. * @param The type to deserialize the result of the request to. * @return The prepared get request. */ public OrchestrateRequest> get(final Class clazz) { checkNotNull(clazz, "clazz"); checkNotNull(type, "type"); final String uri = client.uri(collection, key, "events", type); String query = "limit=".concat(Integer.toString(limit)); final HttpRequestPacket.Builder httpHeaderBuilder = HttpRequestPacket.builder() .method(Method.GET) .uri(uri); if (start != null) { query += "&start=" + start; } if (end != null) { query += "&end=" + end; } if (withFields != null) { query = query.concat("&with_fields=").concat(client.encode(withFields)); } if (withoutFields != null) { query = query.concat("&without_fields=").concat(client.encode(withoutFields)); } httpHeaderBuilder.query(query); final HttpContent packet = httpHeaderBuilder.build() .httpContentBuilder() .build(); return new OrchestrateRequest>(client, packet, new ResponseConverter>() { @Override public EventList from(final HttpContent response) throws IOException { final int status = ((HttpResponsePacket) response.getHttpHeader()).getStatus(); assert (status == 200); final JsonNode jsonNode = toJsonNode(response); final int count = jsonNode.get("count").asInt(); final List> events = new ArrayList>(count); final Iterator iter = jsonNode.get("results").elements(); while (iter.hasNext()) { final JsonNode result = iter.next(); events.add(ResponseConverterUtil.wrapperJsonToEvent(mapper, result, clazz)); } return new EventList(events); } }); } /** * {@link #put(Object, Long)}. * @deprecated Use {@link #create(Object)} for adding new events, and SingleEventResource's 'update' * (via {@link #ordinal(String)}) for updating existing event instances. * @param value The value for the event. * @return The prepared put request. */ @Deprecated public OrchestrateRequest put(final @NonNull Object value) { // Does NOT refer to current 'timestamp' because that is not how legacy worked (pre-deprecation). return put(value, null); } /** * Store an event to a key in the Orchestrate service. * *

Usage:

*
     * {@code
     * DomainObject obj = new DomainObject(); // a POJO
     * boolean result =
     *         client.event("someCollection", "someKey")
     *               .type("someType")
     *               .put(obj)
     *               .get();
     * }
     * 
* * @param value The object to store as the event. * @param timestamp The timestamp to store the event at. * @return The prepared put request. * @deprecated Use {@link #create(Object)} for adding new events, and SingleEventResource's 'update' * (via {@link #ordinal(String)}) for updating existing event instances. */ @Deprecated public OrchestrateRequest put( final @NonNull Object value, @Nullable final Long timestamp) { checkNotNull(type, "type"); checkArgument(start == null && end == null, "'start' and 'end' not allowed with PUT requests."); final byte[] content = toJsonBytes(value); final String uri = client.uri(collection, key, "events", type); final HttpRequestPacket.Builder httpHeaderBuilder = HttpRequestPacket.builder() .method(Method.PUT) .contentType("application/json") .uri(uri); if (timestamp != null) { httpHeaderBuilder.query("timestamp=" + timestamp); } httpHeaderBuilder.contentLength(content.length); final HttpContent packet = httpHeaderBuilder.build() .httpContentBuilder() .content(new ByteBufferWrapper(ByteBuffer.wrap(content))) .build(); return new OrchestrateRequest(client, packet, new ResponseConverter() { @Override public Boolean from(final HttpContent response) throws IOException { final int status = ((HttpResponsePacket) response.getHttpHeader()).getStatus(); return (status == 204); } }); } /** * Add an event to a key in the Orchestrate service. * *

Usage:

*
     * {@code
     * DomainObject obj = new DomainObject(); // a POJO
     * EventMetadata eventMeta =
     *         client.event("someCollection", "someKey")
     *               .type("someType")
     *               .create(obj)
     *               .get();
     * }
     * 
* *
     * To add an event to a specific timestamp:
     * {@code
     * DomainObject obj = new DomainObject(); // a POJO
     * EventMetadata eventMeta =
     *         client.event("someCollection", "someKey")
     *               .type("someType")
     *               .timestamp(someTimestamp)
     *               .create(obj)
     *               .get();
     * }
     * 
* @param value The object to store as the event. * @return The prepared create request. */ public OrchestrateRequest create(final @NonNull Object value) { checkNotNull(type, "type"); checkArgument(start == null && end == null, "'start' and 'end' not allowed with 'create' requests."); final byte[] content = toJsonBytes(value); final String uri; if(timestamp != null) { uri = client.uri(collection, key, "events", type, ""+timestamp); } else { uri = client.uri(collection, key, "events", type); } final HttpRequestPacket.Builder httpHeaderBuilder = HttpRequestPacket.builder() .method(Method.POST) .contentType("application/json") .uri(uri); httpHeaderBuilder.contentLength(content.length); final HttpContent packet = httpHeaderBuilder.build() .httpContentBuilder() .content(new ByteBufferWrapper(ByteBuffer.wrap(content))) .build(); return new OrchestrateRequest(client, packet, new ResponseConverter() { @Override public EventMetadata from(final HttpContent response) throws IOException { final HttpHeader header = response.getHttpHeader(); final int status = ((HttpResponsePacket) header).getStatus(); if (status == 201) { final String location = header.getHeader(Header.Location); // /v0/{coll}/{key}/events/{type}/{timestamp}/{ordinal} final String[] parts = location.split("/"); Long timestamp = new Long(parts[6]); String ordinal = parts[7]; final String ref = header.getHeader(Header.ETag) .replace("\"", "") .replace("-gzip", ""); return new Event(mapper, collection, key, type, timestamp, ordinal, ref, null, null, null, null); } return null; } }); } /** * The type for an event, e.g. "update" or "tweet" etc. * * @param type The type of the event. * @return The event resource. */ public EventResource type(final String type) { this.type = checkNotNullOrEmpty(type, "type"); return this; } public EventResource limit(final int limit) { this.limit = checkNotNegative(limit, "limit"); return this; } /** * The timestamp for an event. * * @param timestamp The timestamp of the event. * @return The event resource. */ public EventResource timestamp(final Long timestamp) { this.timestamp = timestamp; return this; } /** * Called to make operations for an individual event instance. {@link #type} * and {@link #timestamp} must be called prior to calling this method. * *

Usage:

*
     * {@code
     * // fetches a single event instance
     * Event<String> event =
     *         client.event("someCollection", "someKey")
     *               .type("someType")
     *               .timestamp(someTimestamp)
     *               .ordinal(someOrdinal)
     *               .get(String.class)
     *               .get();
     * }
     * 
* * @param ordinal The event instance's ordinal value. * @return A SingleEventResource that can be used to perform operations for * the individual event instance. */ public SingleEventResource ordinal(final String ordinal) { checkNotNull(type, "type"); checkNotNull(timestamp, "timestamp"); checkNotNullOrEmpty(ordinal, "ordinal"); return new SingleEventResource(client, jacksonMapper, collection, key, type, timestamp, ordinal, withFields, withoutFields); } /** * The inclusive start of a time range to query. * * @param start The timestamp to get events from. * @return The event resource. */ public EventResource start(final long start) { this.start = start; return this; } /** * The exclusive end of a time range to query. * * @param end The timestamp to get events up to. * @return The event resource. */ public EventResource end(final long end) { this.end = end; return this; } /** * Apply field-filtering to the result JSON, using this list of fully-qualified * field names as a whitelist of fields to include. * *

* {@code * // fetches a single event instance * Event<String> event = * client.event("someCollection", "someKey") * .type("someType") * .timestamp(someTimestamp) * .ordinal(someOrdinal) * .withFields("value.name.first,value.name.last") * .get(String.class) * .get(); * } *

* * @param withFields The comma separated list of fully-qualified field names to select. * @return This request. */ public EventResource withFields(final String withFields) { this.withFields = checkNotNull(withFields, "withFields"); return this; } /** * Apply field-filtering to the result JSON, using this list of fully-qualified * field names as a blacklist of fields to exclude. * *

* {@code * // fetches a single event instance * Event<String> event = * client.event("someCollection", "someKey") * .type("someType") * .timestamp(someTimestamp) * .ordinal(someOrdinal) * .withoutFields("value.name.first,value.name.last") * .get(String.class) * .get(); * } *

* * @param withoutFields The comma separated list of fully-qualified field names to reject. * @return This request. */ public EventResource withoutFields(final String withoutFields) { this.withoutFields = checkNotNull(withoutFields, "withoutFields"); return this; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy