co.cask.cdap.common.queue.QueueName.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.common.queue.QueueName.java

Source

/*
 * Copyright  2014-2015 Cask Data, Inc.
 *
 * 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 co.cask.cdap.common.queue;

import co.cask.cdap.proto.Id;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;

import java.net.URI;
import java.util.Iterator;

/**
 * An abstraction over URI of a queue.
 */
public final class QueueName {

    /**
     * URI of the queue.
     */
    private final URI uri;

    /**
     * The components of the URI.
     */
    private final String[] components;

    /**
     * Represents the queue as byte[].
     */
    private final byte[] byteName;

    /**
     * Represents the queue name as a string.
     */
    private final String stringName;

    /**
     * Constructs this class from an URI.
     *
     * @param uri of the queue
     * @return An instance of {@link QueueName}
     */
    public static QueueName from(URI uri) {
        Preconditions.checkNotNull(uri, "URI cannot be null.");
        return new QueueName(uri);
    }

    /**
     * Constructs this class from byte array of queue URI.
     *
     * @param bytes respresenting URI
     * @return An instance of {@link QueueName}
     */
    public static QueueName from(byte[] bytes) {
        return new QueueName(URI.create(new String(bytes, Charsets.US_ASCII)));
    }

    public static QueueName fromFlowlet(Id.Flow flow, String flowlet, String output) {
        return fromFlowlet(flow.getNamespaceId(), flow.getApplicationId(), flow.getId(), flowlet, output);
    }

    public static QueueName fromFlowlet(Id.Namespace namespace, String app, String flow, String flowlet,
            String output) {
        return fromFlowlet(namespace.getId(), app, flow, flowlet, output);
    }

    public static QueueName fromFlowlet(String namespace, String app, String flow, String flowlet, String output) {
        URI uri = URI.create(String.format("queue:///%s/%s/%s/%s/%s", namespace, app, flow, flowlet, output));
        return new QueueName(uri);
    }

    public static String prefixForFlow(Id.Flow flowId) {
        // queue:///namespace/app/flow/
        // Note that the trailing / is crucial, otherwise this could match queues of flow1, flowx, etc.
        return String.format("queue:///%s/%s/%s/", flowId.getNamespaceId(), flowId.getApplicationId(),
                flowId.getId());
    }

    // Note that like above the trailing '/' in the prefix for namespace is crucial,
    // otherwise this could match namespaces of ns, ns1, nsx, etc.
    public static String prefixForNamespacedQueue(String namespace) {
        // queue:///namespace/
        return String.format("queue:///%s/", namespace);
    }

    public static String prefixForNamedspacedStream(String namespace) {
        // stream:///namespace/
        return String.format("stream:///%s/", namespace);
    }

    /**
     * Generates an QueueName for the stream.
     *
     * @param namespace of the stream
     * @param stream name of the stream
     * @return An {@link QueueName} with schema as stream
     */
    public static QueueName fromStream(String namespace, String stream) {
        // The old stream admin uses full URI of queue name as the name
        URI uri = URI.create(String.format("stream:///%s/%s", namespace, stream));
        return new QueueName(uri);
    }

    public static QueueName fromStream(Id.Stream streamId) {
        return fromStream(streamId.getNamespaceId(), streamId.getId());
    }

    public Id.Stream toStreamId() {
        return Id.Stream.from(getFirstComponent(), getSecondComponent());
    }

    /**
     * Called from static method {@code QueueName#from(URI)} and {@code QueueName#from(bytes[])}.
     *
     * @param uri of the queue.
     */
    private QueueName(URI uri) {
        this.uri = uri;
        this.stringName = uri.toASCIIString();
        this.byteName = stringName.getBytes(Charsets.US_ASCII);
        Iterable<String> comps = Splitter.on('/').omitEmptyStrings().split(uri.getPath());
        components = new String[Iterables.size(comps)];
        Iterator<String> iter = comps.iterator();
        for (int i = 0; i < components.length; i++) {
            components[i] = iter.next();
        }
    }

    public boolean isStream() {
        return "stream".equals(uri.getScheme());
    }

    public boolean isQueue() {
        return "queue".equals(uri.getScheme());
    }

    private String getNthComponent(int n) {
        return n < components.length ? components[n] : null;
    }

    /**
     * @return the first component of the of the URI (the namespace)
     */
    public String getFirstComponent() {
        return getNthComponent(0);
    }

    /**
     * @return the second component of the URI (the app for a queue, the stream name for a stream).
     */
    public String getSecondComponent() {
        return getNthComponent(1);
    }

    /**
     * @return the third component of the URI (the flow for a queue, null for a stream).
     */
    public String getThirdComponent() {
        return getNthComponent(2);
    }

    /**
     * @return the fourth component of the URI (the flowlet for a queue, null for a stream).
     */
    public String getFourthComponent() {
        return getNthComponent(3);
    }

    /**
     * @return Simple name which is the last part of queue URI path and endpoint.
     */
    public String getSimpleName() {
        return components[components.length - 1];
    }

    /**
     * @return the number of components in the queue name
     */
    public int getNumComponents() {
        return components.length;
    }

    /**
     * Gets the bytes representation of the queue uri. Note that mutating the returned array will mutate the underlying
     * byte array as well. If mutation is needed, one has to copy to a separate array.
     *
     * @return bytes representation of queue uri.
     */
    public byte[] toBytes() {
        return byteName;
    }

    /**
     * @return A {@link URI} representation of the queue name.
     */
    public URI toURI() {
        return uri;
    }

    /**
     * @return converts to ascii string.
     */
    @Override
    public String toString() {
        return stringName;
    }

    /**
     * @return whether the given string represents a queue.
     */
    public static boolean isQueue(String name) {
        return name.startsWith("queue");
    }

    /**
     * @return whether the given string represents a queue.
     */
    public static boolean isStream(String name) {
        return name.startsWith("stream");
    }

    /**
     * Compares this {@link QueueName} with another {@link QueueName}.
     *
     * @param o Other instance of {@link QueueName}
     * @return true if equal; false otherwise.
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        return uri.equals(((QueueName) o).uri);
    }

    /**
     * @return hash code of this QueueName.
     */
    @Override
    public int hashCode() {
        return uri.hashCode();
    }
}