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

org.openstack4j.core.transport.HttpRequest Maven / Gradle / Ivy

package org.openstack4j.core.transport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.openstack4j.api.EndpointTokenProvider;
import org.openstack4j.api.types.ServiceType;
import org.openstack4j.model.ModelEntity;
import org.openstack4j.model.common.Payload;

import com.google.common.base.Function;
import com.google.common.collect.Maps;

/**
 * A Request Delegate which aids in building the request that is compatible with the OpenStack Rest API. The request is used to encoding as well as keeping reference to 
 * the return type
 * 
 * @param  the entity return type
 * @author Jeremy Unruh
 */
public class HttpRequest {


	String endpoint;
	String path;
	Class returnType;
	Object entity;
	String contentType = ClientConstants.CONTENT_TYPE_JSON;
	HttpMethod method = HttpMethod.GET;
	String json;
	private Config config;
	private Map> queryParams;
	private Map headers = new HashMap();
	private Function endpointFunc;
	public HttpRequest() { }

	/**
	 * Creates a new HttpRequest
	 *
	 * @param endpoint the endpoint URI
	 * @param path the path which will be appended to the endpoint URI
	 * @param method the method the method type to invoke
	 * @param entity the entity (used for posts)
	 * @param returnType the expected return type
	 */
	public HttpRequest(String endpoint, String path, HttpMethod method, ModelEntity entity, Class returnType) {
		this.endpoint = endpoint;
		this.path = path;
		this.method = method;
		this.entity = entity;
	}

	/**
	 * A build for creating HttpRequest objects
	 *
	 * @return the request builder
	 */
	public static RequestBuilder builder() {
		return new RequestBuilder(Void.class);
	}

	/**
	 * A build for creating HttpRequest objects
	 *
	 * @param  the expected return type
	 * @param returnType the return type
	 * @return the request builder
	 */
	public static  RequestBuilder builder(Class returnType) {
		return new RequestBuilder(returnType);
	}

	/**
	 * @return the method this request will use
	 */
	public HttpMethod getMethod() {
		return method;
	}
	
	/**
	 * @return the content type for the request
	 */
	public String getContentType() {
		return contentType;
	}

	/**
	 * @return the endpoint URI
	 */
	public String getEndpoint() {
		if (endpointFunc != null)
			return endpointFunc.apply(endpoint);
		return endpoint;
	}
	
	/**
	 * @return the http path
	 */
	public String getPath() {
		return path;
	}
	
	/**
	 * If JSON is explicitly set vs an entity then this method will return a JSON String otherwise Empty
	 * @return JSON String form or Empty
	 */
	public String getJson() {
		return (json == null) ? "" : json;
	}
	
	/**
	 * @return true, if a JSON Object has been set
	 */
	public boolean hasJson() {
		return (json != null);
	}
	
	/**
	 * @return the return type expected after invocation
	 */
	public Class getReturnType() {
		return returnType;
	}
	
	/**
	 * @return the entity to post
	 */
	public Object getEntity() {
		return entity;
	}
	
	/**
	 * @return true, if query params have been added
	 */
	public boolean hasQueryParams() {
		return queryParams != null && !queryParams.isEmpty();
	}

	/**
	 * @return the request query params
	 */
	public Map> getQueryParams() {
		return queryParams;
	}

	/**
	 * @return the headers to apply
	 */
	public Map getHeaders() {
		return headers;
	}

	/**
	 * @return true, if headers have been added
	 */
	public boolean hasHeaders() {
		return !headers.isEmpty();
	}
	
	public RequestBuilder toBuilder() {
	    return new RequestBuilder(this);
	}
	
	/**
	 * @return the client configuration associated with this request
	 */
	public Config getConfig() {
	    return config != null ? config : Config.DEFAULT;
	}

	public static final class RequestBuilder {

		HttpRequest request;
		EndpointTokenProvider provider;
		ServiceType service;
		
		public RequestBuilder(HttpRequest request) {
		    this.request = request;
		}
		
		public RequestBuilder(Class returnType) {
			request = new HttpRequest();
			request.returnType = returnType;
		}

		/**
		 * @see HttpRequest#getEndpoint()
		 */
		public RequestBuilder endpoint(String endpoint) {
			request.endpoint = endpoint;
			return this;
		}

		/**
		 * @see HttpRequest#getPath()
		 */
		public RequestBuilder path(String path) {
			request.path = path;
			return this;
		}

		/**
		 * @see HttpRequest#getMethod()
		 */
		public RequestBuilder method(HttpMethod method) {
			request.method = method;
			return this;
		}
		
		/**
		 * A Function which allows manipulation of the endpoint depending on the service API utilizing it
		 * @param endpointFunc the function to modify the current endpoint into a resulting endpoint
		 * @return this
		 */
		public RequestBuilder endpointFunction(Function endpointFunc) {
			request.endpointFunc = endpointFunc;
			return this;
		}
 
		/**
		 * Flags the request method as PUT
		 *
		 * @return the request builder
		 */
		public RequestBuilder methodPut() {
			request.method = HttpMethod.PUT;
			return this;
		}

		/**
		 * Flags the request method as GET
		 *
		 * @return the request builder
		 */
		public RequestBuilder methodGet() {
			request.method = HttpMethod.GET;
			return this;
		}

		/**
		 * Flags the request method as DELETE
		 *
		 * @return the request builder
		 */
		public RequestBuilder methodDelete() {
			request.method = HttpMethod.DELETE;
			return this;
		}

		/**
		 * Flags the request method as POST
		 *
		 * @return the request builder
		 */
		public RequestBuilder methodPost() {
			request.method = HttpMethod.POST;
			return this;
		}
		
		/**
		 * @see HttpRequest#getEntity()
		 */
		public RequestBuilder entity(ModelEntity entity) {
			request.entity = entity;
			return this;
		}
		
		/**
		 * @see HttpRequest#getEntity()
		 */
		public RequestBuilder entity(Payload entity) {
			if (entity != null)
			  request.entity = entity.open();
			return this;
		}
		
		/**
         * Sets a client configuration to use with this session
         */
        public RequestBuilder config(Config config) {
            request.config = config;
            return this;
        }
		
		/**
		 * Pushes the Map of Headers into the existing headers for this request
		 * @param headers the headers to append
		 * @return the request builder
		 */
		public RequestBuilder headers(Map headers) {
			request.getHeaders().putAll(headers);
			return this;
		}
		
		/**
		 * Adds a new Header to the request
		 * @param name the header name
		 * @param value the header value
		 * @return the request builder
		 */
		public RequestBuilder header(String name, Object value) {
			request.getHeaders().put(name, value);
			return this;
		}
		
		/**
		 * The endpoint Service Type
		 *
		 * @param service the service type
		 * @return the request builder
		 */
		public RequestBuilder serviceType(ServiceType service) {
			this.service = service;
			return this;
		}

		/**
		 * Adds a Key/Value based Query Param     
		 *
		 * @param key the key
		 * @param value the value
		 * @return the request builder
		 */
		public RequestBuilder queryParam(String key, Object value) {
		    if (value == null)
		        return this;
		    
			if (request.queryParams == null)
				request.queryParams = Maps.newHashMap();

			if (request.queryParams.containsKey(key)) {
				List values = request.queryParams.get(key);
				values.add(value);
			} else {
				List values = new ArrayList();
				values.add(value);
				request.queryParams.put(key, values);
			}
			return this;
		}
        /**
         * Updates a Key/Value based Query Param     
         *
         * @param key the key
         * @param value the value
         * @return the request builder
         */
        public RequestBuilder updateQueryParam(String key, Object value) {
            if (value == null)
                return this;
            
            if (request.queryParams == null)
                request.queryParams = Maps.newHashMap();

            List values = new ArrayList();
            values.add(value);
            request.queryParams.put(key, values);
            
            return this;
        }
		/**
		 * A Provider which will return the current Authorization Token
		 *
		 * @param provider the provider
		 * @return the request builder
		 */
		public RequestBuilder endpointTokenProvider(EndpointTokenProvider provider) {
			this.provider = provider;
			return this;
		}
		
		/**
		 * AdHoc JSON object to Post/Put
		 *
		 * @param json the JSON object in String form
		 * @return the request builder
		 */
		public RequestBuilder json(String json) {
			request.json = json;
			return this;
		}
		
		/**
		 * Overrides the default content type for the request
		 * 
		 * @param contentType the content type to use in the request
		 * @return the request builder
		 */
		public RequestBuilder contentType(String contentType) {
		    if (contentType != null)
		        request.contentType = contentType;
			return this;
		}

		/**
		 * Builds the HttpRequest
		 *
		 * @return HttpRequest
		 */
		public HttpRequest build() {
			if (provider != null)
			{
				request.endpoint = provider.getEndpoint(service);
				if (provider.getTokenId() != null)
				    request.getHeaders().put(ClientConstants.HEADER_X_AUTH_TOKEN, provider.getTokenId());
			}
			return request;
		}
	}
}