package com.jdroid.java.http.mock; import com.jdroid.java.collections.Lists; import com.jdroid.java.collections.Maps; import com.jdroid.java.concurrent.ExecutorUtils; import com.jdroid.java.exception.UnexpectedException; import com.jdroid.java.http.HttpResponseWrapper; import com.jdroid.java.http.HttpService; import com.jdroid.java.http.HttpServiceProcessor; import com.jdroid.java.http.MultipartHttpService; import com.jdroid.java.http.parser.Parser; import com.jdroid.java.http.post.BodyEnclosingHttpService; import com.jdroid.java.utils.FileUtils; import com.jdroid.java.utils.LoggerUtils; import com.jdroid.java.utils.StringUtils; import org.slf4j.Logger; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.Collection; import java.util.List; import java.util.Map; /** * Mocked {@link HttpService} and {@link BodyEnclosingHttpService} implementation that returns mocked responses */ public abstract class AbstractMockHttpService implements MultipartHttpService { private static final Logger LOGGER = LoggerUtils.getLogger(AbstractMockHttpService.class); private static final String MOCK_SEPARATOR = "_"; private static final String SUFFIX_SEPARATOR = "-"; private static final String URL_SEPARATOR = "/"; private List<Object> urlSegments; private Map<String, String> parameters = Maps.newHashMap(); private Map<String, String> headers = Maps.newHashMap(); private String body; public AbstractMockHttpService(Object... urlSegments) { this.urlSegments = Lists.newArrayList(); if (urlSegments != null) { for (Object segment : urlSegments) { addUrlSegment(segment); } } } /** * @see HttpService#execute(Parser) */ @SuppressWarnings({ "unchecked", "resource" }) @Override public <T> T execute(Parser parser) { String filePath = generateMockFilePath(urlSegments); LOGGER.warn("Request: " + filePath); if (!parameters.isEmpty()) { LOGGER.warn("Parameters: " + parameters.toString()); } if (!headers.isEmpty()) { LOGGER.warn("Headers: " + headers.toString()); } if (StringUtils.isNotBlank(body)) { LOGGER.warn("HTTP Entity Body: " + body); } Integer httpMockSleep = getHttpMockSleepDuration(urlSegments.toArray()); if ((httpMockSleep != null) && (httpMockSleep > 0)) { ExecutorUtils.sleep(httpMockSleep); } simulateCrash(); if (parser != null) { InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filePath); if (inputStream == null) { throw new UnexpectedException("The mocked file wasn't found"); } // Parse the stream T t = (T)(parser.parse(inputStream)); FileUtils.safeClose(inputStream); return t; } else { return null; } } @Override public void execute() { execute(null); } protected void simulateCrash() { // Do nothing by default } /** * @see HttpService#addHeader(java.lang.String, java.lang.String) */ @Override public void addHeader(String name, String value) { if (value != null) { headers.put(name, value); } } /** * @see HttpService#addQueryParameter(java.lang.String, java.lang.Object) */ @Override public void addQueryParameter(String name, Object value) { if (value != null) { parameters.put(name, value.toString()); } } /** * @see HttpService#addQueryParameter(java.lang.String, java.util.Collection) */ @Override public void addQueryParameter(String name, Collection<?> values) { addQueryParameter(name, StringUtils.join(values)); } /** * @see MultipartHttpService#addPart(java.lang.String, java.io.ByteArrayInputStream, * java.lang.String, java.lang.String) */ @Override public void addPart(String name, ByteArrayInputStream in, String mimeType, String filename) { // Do Nothing } /** * @see MultipartHttpService#addPart(java.lang.String, java.lang.Object, java.lang.String) */ @Override public void addPart(String name, Object value, String mimeType) { // Do Nothing } /** * @see MultipartHttpService#addJsonPart(java.lang.String, java.lang.Object) */ @Override public void addJsonPart(String name, Object value) { // Do Nothing } /** * @see HttpService#addUrlSegment(java.lang.Object) */ @Override public void addUrlSegment(Object segment) { String segmentString = segment.toString(); if (StringUtils.isNotEmpty(segmentString)) { urlSegments.add(segmentString); } } /** * @see HttpService#addHttpServiceProcessor(HttpServiceProcessor) */ @Override public void addHttpServiceProcessor(HttpServiceProcessor httpServiceProcessor) { // Do Nothing } /** * @see BodyEnclosingHttpService#setBody(String) */ @Override public void setBody(String body) { this.body = body; } /** * @see HttpService#setConnectionTimeout(java.lang.Integer) */ @Override public void setConnectionTimeout(Integer connectionTimeout) { // Do Nothing } @Override public void setReadTimeout(Integer readTimeout) { // Do Nothing } @Override public void setWriteTimeout(Integer writeTimeout) { // Do Nothing } /** * @see HttpService#setUserAgent(java.lang.String) */ @Override public void setUserAgent(String userAgent) { // Do Nothing } /** * @see HttpService#setSsl(java.lang.Boolean) */ @Override public void setSsl(Boolean ssl) { // Do Nothing } /** * @return The time to sleep (in seconds) to simulate the execution of the request */ protected abstract Integer getHttpMockSleepDuration(Object... urlSegments); /** * @see HttpService#getUrl() */ @Override public String getUrl() { return generateMockFilePath(urlSegments); } /** * @see HttpService#getUrlSuffix() */ @Override public String getUrlSuffix() { return null; } protected String generateMockFilePath(List<Object> urlSegments) { StringBuilder sb = new StringBuilder(getMocksBasePath()); if (urlSegments != null) { for (Object urlSegment : urlSegments) { sb.append(urlSegment.toString().replaceAll(URL_SEPARATOR, MOCK_SEPARATOR)); sb.append(MOCK_SEPARATOR); } } sb.deleteCharAt(sb.length() - 1); String suffix = getSuffix(sb.toString()); if (StringUtils.isNotBlank(suffix)) { sb.append(SUFFIX_SEPARATOR); sb.append(suffix); } sb.append(getMocksExtension()); return sb.toString(); } /** * @return The mocks base path */ protected abstract String getMocksBasePath(); /** * @return The mocks extension */ protected abstract String getMocksExtension(); /** * @return The suffix to add to the mock file */ protected String getSuffix(String path) { return null; } @Override public String getHeaderValue(String key) { return headers.get(key); } @Override public HttpResponseWrapper getHttpResponseWrapper() { return null; } }