/*
* Copyright (c) 2013-2017 Cinchapi 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 com.cinchapi.concourse.server.http;
import javax.annotation.Nullable;
import com.cinchapi.concourse.thrift.AccessToken;
import com.cinchapi.concourse.thrift.TransactionToken;
import com.google.gson.JsonObject;
/**
* An {@link Endpoint} is the most basic construct in the HTTP framework. An
* Endpoint is uniquely identifiable and accessible from a <em<route</em> that
* is made up of an HTTP verb/action and a URI.
* <p>
* An Endpoint's route can be provided upon
* {@link Endpoint#Endpoint(String, String) construction} or it can be inferred
* from the name of the instance variable to which the Endpoint is bound in an
* {@link EndpointContainer}.
* </p>
* <p>
* When declaring Endpoints anonymously within an {@link EndpointContainer}, be
* sure to use variable names that conform to the roting spec.
* </p>
*
* @author Jeff Nelson
*/
public abstract class Endpoint {
/**
* Create an {@link Endpoint} that is bound to a variable whose name is used
* to assign the {@link #getAction() action} and {@link #getPath() path}.
*/
public Endpoint() {
this(null, null);
}
/**
* Create an {@link Endpoint} that uses the provided {@code action} and
* {@code path}.
*
* @param action the HTTP verb to which this {@link Endpoint} responds
* @param path the relative path of the {@link Endpoint}
*/
public Endpoint(String action, String path) {
this.action = action;
this.path = path;
}
/**
* A {@link JsonElement} that represents the lack of any data being
* returned.
*/
protected static JsonObject NO_DATA = new JsonObject();
/**
* The HTTP verb to which this endpoint responds.
*/
private String action;
/**
* The full URI at which this endpoint is reachable.
*/
private String path;
/**
* Return the HTTP verb/action to which this endpoint responds.
* <p>
* This value is configured using {@link #setAction(String)}.
* </p>
*
* @return the action for this Endpoint
*/
public String getAction() {
return action;
}
/**
* Return the content type that this {@link Endpoint} returns from the
* {@link #serve(HttpRequest, HttpResponse, AccessToken, TransactionToken, String)}
* method.
*
* @return the content type
*/
public ContentType getContentType() {
return ContentType.JSON;
}
/**
* Return the path at which this endpoint is reachable.
*
* @return the path for this Endpoint
*/
public String getPath() {
return path;
}
/**
* Serve the {@code request} and return the appropriate payload with the
* {@code response}.
*
* <p>
* If this method returns, it is assumed that the request was successful.
* If, for any reason, an error occurs, this method should throw an
* Exception and it will be wrapped in the appropriate response for the
* caller.
* </p>
*
* @param request an {@link HttpRequest object} that contains all the
* information about the request
* @param response an {@link HttpResponse object} that contains all the
* information that should be issued within the response
* @param creds an {@link AccessToken} for the authenticated user, if a user
* session exists
* @param transaction a {@link TransactionToken} for appropriately routing
* the data actions
* @param environment the environment of the {@link ConcourseRuntime} in
* which the data action should occur
* @return the payload
* @throws Exception
*/
public abstract String serve(HttpRequest request, HttpResponse response,
@Nullable AccessToken creds,
@Nullable TransactionToken transaction, String environment)
throws Exception;
/**
* Items that can be returned from the {@link Endpoint#getContentType()}
* method.
*
* @author Jeff Nelson
*/
public enum ContentType {
JSON;
@Override
public String toString() {
switch (this) {
case JSON:
return "application/json";
default:
return "text/html";
}
}
}
}