package com.github.kristofa.test.http.file;
import java.io.File;
import com.github.kristofa.test.http.AbstractHttpResponseProvider;
import com.github.kristofa.test.http.HttpRequest;
import com.github.kristofa.test.http.HttpResponseProvider;
import com.github.kristofa.test.http.LoggingHttpProxy;
/**
* {@link HttpResponseProvider} that is able to serve responses for requests/responses previously saved by
* {@link HttpRequestResponseFileLogger}.
* <p>
* It supports submitting same request multiple times with different return result.
* <p>
* It reads all http requests on construction and keeps them in memory. It does not keep responses in memory. They are read
* from disk on request and not cached.
*
* @see HttpRequestResponseFileLogger
* @see LoggingHttpProxy
* @author kristof
*/
public class FileHttpResponseProvider extends AbstractHttpResponseProvider {
private final String directory;
private final String fileName;
private final HttpRequestFileReader httpRequestFileReader;
private final HttpResponseFileReader httpResponseFileReader;
/**
* Creates a new instance. Will try to find request/response files and will throw unchecked exception in case:
* <ul>
* <li>We can not find at least 1 request/response for given directory and file name.
* <li>We found a request without persisted response
* </ul>
*
* @param directory Directory from which to read files.
* @param fileName Base file name. Should not contain extension. Will be suffixed with sequence number and .txt
* extension. Should be same as used in {@link HttpRequestResponseFileLogger}.
*/
public FileHttpResponseProvider(final String directory, final String fileName) {
this(directory, fileName, new HttpRequestFileReaderImpl(), new HttpResponseFileReaderImpl());
}
/**
* Creates a new instance. Will try to find request/response files and will throw unchecked exception in case:
* <ul>
* <li>We can not find at least 1 request/response for given directory and file name.
* <li>We found a request without persisted response
* </ul>
*
* @param directory Directory from which to read files.
* @param fileName Base file name. Should not contain extension. Will be suffixed with sequence number and .txt
* extension. Should be same as used in {@link HttpRequestResponseFileLogger}.
* @param requestFileReader HTTP request file reader.
* @param responseFileReader HTTP response file reader.
*/
public FileHttpResponseProvider(final String directory, final String fileName,
final HttpRequestFileReader requestFileReader, final HttpResponseFileReader responseFileReader) {
this.directory = directory;
this.fileName = fileName;
httpRequestFileReader = requestFileReader;
httpResponseFileReader = responseFileReader;
}
/**
* {@inheritDoc}
*/
@Override
protected void lazyInitializeExpectedRequestsAndResponses() {
int seqNr = 1;
File requestFile = new File(directory, FileNameBuilder.REQUEST_FILE_NAME.getFileName(fileName, seqNr));
if (!requestFile.exists()) {
throw new IllegalStateException("No saved http request/responses found. File " + requestFile + " not found.");
}
while (requestFile.exists()) {
final File responseFile = new File(directory, FileNameBuilder.RESPONSE_FILE_NAME.getFileName(fileName, seqNr));
if (!responseFile.exists()) {
throw new IllegalStateException("Found request file (" + requestFile + ") but no matching response file: "
+ responseFile);
}
submitRequest(fileName, seqNr);
seqNr++;
requestFile = new File(directory, FileNameBuilder.REQUEST_FILE_NAME.getFileName(fileName, seqNr));
}
}
private void submitRequest(final String fileName, final int seqNr) {
final File requestFile = new File(directory, FileNameBuilder.REQUEST_FILE_NAME.getFileName(fileName, seqNr));
final File requestEntityFile =
new File(directory, FileNameBuilder.REQUEST_ENTITY_FILE_NAME.getFileName(fileName, seqNr));
final HttpRequest request = httpRequestFileReader.read(requestFile, requestEntityFile);
final FileHttpResponseProxy responseProxy =
new FileHttpResponseProxy(directory, fileName, seqNr, httpResponseFileReader);
addExpected(request, responseProxy);
}
}