/*******************************************************************************
* Copyright (c) 2011 Subgraph.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Subgraph - initial API and implementation
******************************************************************************/
package com.subgraph.vega.internal.model.requests;
import java.util.Date;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import com.db4o.activation.ActivationPurpose;
import com.db4o.activation.Activator;
import com.db4o.ta.Activatable;
import com.subgraph.vega.api.model.requests.IRequestLogRecord;
public class RequestLogRecord implements IRequestLogRecord, Activatable {
final long requestId;
private final HttpRequest request;
private final HttpHost host;
private String hostname;
private String requestMethod;
private String requestPath;
private String requestHeaders;
private int responseCode;
private int responseLength;
private String responseHeaders;
private HttpResponse response;
private final long timestamp;
private long requestTimeMs;
private transient Activator activator;
RequestLogRecord() {
requestId = 0;
request = null;
response = null;
host = null;
timestamp = 0;
requestTimeMs = -1;
setCachedRequestFields(null, null);
setCachedResponseFields(null);
}
RequestLogRecord(long requestId, HttpRequest request, HttpResponse response, HttpHost host, long requestTimeMs) {
this.requestId = requestId;
this.request = request;
this.response = response;
this.host = host;
this.timestamp = new Date().getTime();
this.requestTimeMs = requestTimeMs;
setCachedRequestFields(request, host);
setCachedResponseFields(response);
}
RequestLogRecord(long requestId, HttpRequest request, HttpHost host, long requestTimeMs) {
this(requestId, request, null, host, requestTimeMs);
}
private void setCachedRequestFields(HttpRequest request, HttpHost host) {
if(request == null) {
hostname = null;
requestMethod = null;
requestHeaders = null;
requestPath = null;
} else {
hostname = host.getHostName();
requestMethod = request.getRequestLine().getMethod();
requestHeaders = headersToString(request.getAllHeaders());
requestPath = request.getRequestLine().getUri();
}
}
private void setCachedResponseFields(HttpResponse response) {
if(response == null) {
responseCode = 0;
responseLength = 0;
responseHeaders = null;
} else {
responseCode = response.getStatusLine().getStatusCode();
responseLength = (int) getLengthFromResponse(response);
responseHeaders = headersToString(response.getAllHeaders());
}
}
private String headersToString(Header[] headers) {
final StringBuilder sb = new StringBuilder();
for(Header h: headers) {
sb.append(h.getName());
sb.append(": ");
sb.append(h.getValue());
sb.append("\n");
}
return sb.toString();
}
private long getLengthFromResponse(HttpResponse response) {
final Header lengthHeader = response.getFirstHeader("Content-Length");
if(lengthHeader != null) {
try {
return Long.parseLong(lengthHeader.getValue());
} catch (NumberFormatException e) {
return 0;
}
}
if(response.getEntity() == null)
return 0;
return response.getEntity().getContentLength();
}
void setResponse(HttpResponse response) {
activate(ActivationPurpose.WRITE);
this.response = response;
setCachedResponseFields(response);
}
String getHostname() { return hostname; }
String getRequestMethod() { return requestMethod; }
String getRequestHeaders() { return requestHeaders; }
String getRequestPath() { return requestPath; }
int getResponseCode() { return responseCode; }
int getResponseLength() { return responseLength; }
String getResponseHeaders() { return responseHeaders; }
@Override
public long getRequestId() {
activate(ActivationPurpose.READ);
return requestId;
}
@Override
public long getTimestamp() {
activate(ActivationPurpose.READ);
return timestamp;
}
@Override
public long getRequestMilliseconds() {
return requestTimeMs;
}
@Override
public HttpRequest getRequest() {
activate(ActivationPurpose.READ);
return request;
}
@Override
public HttpResponse getResponse() {
activate(ActivationPurpose.READ);
synchronized(response) {
return response;
}
}
@Override
public HttpHost getHttpHost() {
activate(ActivationPurpose.READ);
return host;
}
@Override
public void activate(ActivationPurpose activationPurpose) {
if(activator != null) {
activator.activate(activationPurpose);
}
}
@Override
public void bind(Activator activator) {
if(this.activator == activator) {
return;
}
if(activator != null && this.activator != null) {
throw new IllegalStateException("Object can only be bound to one activator");
}
this.activator = activator;
}
}