/*
* See COPYING for license information.
*/
package com.rackspacecloud.client.cloudfiles;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
public class FilesResponse
{
private HttpResponse response = null;
private HttpEntity entity = null;
private String authToken = null;
private List<FilesRegion> regions = new ArrayList<FilesRegion>();
private static Logger logger = Logger.getLogger(FilesResponse.class);
/**
* @param method The HttpMethod that generated this response
*/
public FilesResponse (HttpResponse response)
{
this.response = response;
entity = response.getEntity();
if (logger.isDebugEnabled())
{
logger.debug ("Status Line: " + getStatusLine());
Header [] responseHeaders = getResponseHeaders();
for (int i=0; i < responseHeaders.length;i++)
logger.debug(responseHeaders[i]);
}
}
/**
* Checks to see if the user managed to login with their credentials.
*
* @return true is login succeeded false otherwise
*/
public boolean loginSuccess ()
{
int statusCode = getStatusCode();
if (statusCode >= 200 && statusCode < 300)
return true;
return false;
}
/**
* This method makes no assumptions about the user having been logged in. It simply looks for the Storage Token header
* as defined by FilesConstants.X_STORAGE_TOKEN and if this exists it returns its value otherwise the value returned will be null.
*
* @return null if the user is not logged into Cloud FS or the Storage token
*/
public String getAuthToken ()
{
//return getResponseHeader(FilesUtil.getProperty("auth_token_name", FilesConstants.X_AUTH_TOKEN)).getValue();
if (authToken == null) {
parseAuthResponse();
}
return this.authToken;
}
/**
* This method makes no assumptions about the user having been logged in. It simply looks for the Storage URL header
* as defined by FilesConstants.X_STORAGE_URL and if this exists it returns its value otherwise the value returned will be null.
*
* @return null if the user is not logged into Cloud FS or the Storage URL
*/
public String getStorageURL ()
{
return getResponseHeader(FilesConstants.X_STORAGE_URL).getValue();
}
/**
* This method makes no assumptions about the user having been logged in. It simply looks for the CDN Management URL header
* as defined by FilesConstants.X_CDN_MANAGEMENT_URL and if this exists it returns its value otherwise the value returned will be null.
*
* @return null if the user is not logged into Cloud FS or the Storage URL
*/
public String getCDNManagementURL ()
{
Header header = getResponseHeader(FilesConstants.X_CDN_MANAGEMENT_URL);
return header == null ? null : header.getValue();
}
/**
* Get the content type
*
* @return The content type (e.g., MIME type) of the response
*/
public String getContentType ()
{
return getResponseHeader("Content-Type").getValue();
}
/**
* Get the content length of the response (as reported in the header)
*
* @return the length of the content
*/
public String getContentLength ()
{
Header hdr = getResponseHeader("Content-Length");
if (hdr == null) return "0";
return hdr.getValue();
}
/**
* The Etag is the same as the objects MD5SUM
*
* @return The ETAG
*/
public String getETag ()
{
Header hdr = getResponseHeader(FilesConstants.E_TAG);
if (hdr == null) return null;
return hdr.getValue();
}
/**
* The last modified header
*
* @return The last modified header
*/
public String getLastModified ()
{
return getResponseHeader("Last-Modified").getValue();
}
/**
* The HTTP headers from the response
*
* @return The headers
*/
public Header[] getResponseHeaders()
{
return response.getAllHeaders();
}
/**
* The HTTP Status line (both the status code and the status message).
*
* @return The status line
*/
public StatusLine getStatusLine()
{
return response.getStatusLine();
}
/**
* Get the HTTP status code
*
* @return The status code
*/
public int getStatusCode ()
{
return response.getStatusLine().getStatusCode();
}
/**
* Get the HTTP status message
*
* @return The message portion of the status line
*/
public String getStatusMessage ()
{
return response.getStatusLine().getReasonPhrase();
}
/**
* The HTTP Method (put, get, etc) of the request that generated this response
*
* @return The method name
*/
/*public String getMethodName ()
{
return response.getName();
}
*/
/**
* Returns the response body as text
*
* @return The response body
* @throws IOException
*/
public String getResponseBodyAsString () throws IOException
{
return EntityUtils.toString(entity);
}
/**
* Get the response body as a Stream
*
* @return An input stream that will return the response body when read
* @throws IOException
*/
public InputStream getResponseBodyAsStream () throws IOException
{
return entity.getContent();
}
/**
* Get the body of the response as a byte array
*
* @return The body of the response.
* @throws IOException
*/
public byte[] getResponseBody () throws IOException
{
return EntityUtils.toByteArray(entity);
}
/**
* Returns the specified response header. Note that header-name matching is case insensitive.
*
* @param headerName - The name of the header to be returned.
* @return The specified response header. If the response contained multiple instances of the header, its values will be combined using the ',' separator as specified by RFC2616.
*/
public Header getResponseHeader(String headerName)
{
return response.getFirstHeader(headerName);
}
/**
* Get the number of objects in the header
*
* @return -1 if the header is not present or the correct value as defined by the header
*/
public int getContainerObjectCount ()
{
Header contCountHeader = getResponseHeader (FilesConstants.X_CONTAINER_OBJECT_COUNT);
if (contCountHeader != null )
return Integer.parseInt(contCountHeader.getValue());
return -1;
}
/**
* Get the number of bytes used by the container
*
* @return -1 if the header is not present or the correct value as defined by the header
*/
public long getContainerBytesUsed ()
{
Header contBytesUsedHeader = getResponseHeader (FilesConstants.X_CONTAINER_BYTES_USED);
if (contBytesUsedHeader != null )
return Long.parseLong(contBytesUsedHeader.getValue());
return -1;
}
/**
* Get the number of objects in the header
*
* @return -1 if the header is not present or the correct value as defined by the header
*/
public int getAccountContainerCount ()
{
Header contCountHeader = getResponseHeader (FilesConstants.X_ACCOUNT_CONTAINER_COUNT);
if (contCountHeader != null )
return Integer.parseInt(contCountHeader.getValue());
return -1;
}
/**
* Get the number of bytes used by the container
*
* @return -1 if the header is not present or the correct value as defined by the header
*/
public long getAccountBytesUsed ()
{
Header accountBytesUsedHeader = getResponseHeader (FilesConstants.X_ACCOUNT_BYTES_USED);
if (accountBytesUsedHeader != null )
return Long.parseLong(accountBytesUsedHeader.getValue());
return -1;
}
/**
* Get the URL For a shared container
*
* @return null if the header is not present or the correct value as defined by the header
*/
public String getCdnUrl ()
{
Header cdnHeader = getResponseHeader (FilesConstants.X_CDN_URI);
if (cdnHeader != null )
return cdnHeader.getValue();
return null;
}
/**
* Get the SSL URL For a shared container
*
* @return null if the header is not present or the correct value as defined by the header
*/
public String getCdnSslUrl ()
{
Header cdnHeader = getResponseHeader (FilesConstants.X_CDN_SSL_URI);
if (cdnHeader != null )
return cdnHeader.getValue();
return null;
}
/**
* Get the SSL URL For a shared container
*
* @return null if the header is not present or the correct value as defined by the header
*/
public String getCdnStreamingUrl ()
{
Header cdnHeader = getResponseHeader (FilesConstants.X_CDN_Streaming_URI);
if (cdnHeader != null )
return cdnHeader.getValue();
return null;
}
/**
* Returns the response headers with the given name. Note that header-name matching is case insensitive.
*
* @param headerName - the name of the headers to be returned.
* @return An array of zero or more headers
*/
public Header[] getResponseHeaders(String headerName)
{
return response.getHeaders(headerName);
}
public String getContentEncoding() {
return entity.getContentEncoding().getValue();
}
public Collection<FilesRegion> getRegions() {
if (authToken == null) {
parseAuthResponse();
}
return regions;
}
private void parseAuthResponse() {
try {
String jsonString = EntityUtils.toString(this.response.getEntity());
JSONObject json = (JSONObject) JSONValue.parse(jsonString);
JSONObject auth = (JSONObject) json.get("auth");
JSONObject token = (JSONObject) auth.get("token");
this.authToken = (String) token.get("id");
Map<String, String> cdnUrls = new HashMap<String, String>();
JSONObject serviceCatalog = (JSONObject) auth.get("serviceCatalog");
JSONArray cdnRegions = (JSONArray) serviceCatalog.get("cloudFilesCDN");
for (int i = 0; i < cdnRegions.size(); i++) {
JSONObject cdnRegion = (JSONObject) cdnRegions.get(i);
String regionId = (String) cdnRegion.get("region");
String publicUrl = (String) cdnRegion.get("publicURL");
cdnUrls.put(regionId, publicUrl);
}
JSONArray filesRegions = (JSONArray) serviceCatalog.get("cloudFiles");
for (int i = 0; i < filesRegions.size(); i++) {
JSONObject filesRegion = (JSONObject) filesRegions.get(i);
String regionId = (String) filesRegion.get("region");
String publicUrl = (String) filesRegion.get("publicURL");
String cdnUrl = cdnUrls.containsKey(regionId) ? cdnUrls.get(regionId) : "";
Boolean v1Default = filesRegion.containsKey("v1Default")
? (Boolean) filesRegion.get("v1Default")
: Boolean.FALSE;
regions.add(new FilesRegion(regionId, publicUrl, cdnUrl, v1Default.booleanValue()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}