/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.apache.shindig.gadgets.http;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.Maps;
import com.google.inject.Provider;
import org.apache.shindig.common.uri.Uri;
import org.apache.shindig.gadgets.AuthType;
import org.apache.shindig.gadgets.GadgetException;
import org.apache.shindig.gadgets.oauth.OAuthRequest;
import org.apache.shindig.gadgets.rewrite.DefaultResponseRewriterRegistry;
import org.junit.Test;
import java.util.Map;
public class DefaultRequestPipelineTest {
private static final Uri DEFAULT_URI = Uri.parse("http://example.org/gadget.xml");
private final FakeHttpFetcher fetcher = new FakeHttpFetcher();
private final FakeHttpCache cache = new FakeHttpCache();
private final FakeOAuthRequestProvider oauth = new FakeOAuthRequestProvider();
private final HttpResponseMetadataHelper helper = new HttpResponseMetadataHelper() {
@Override
public String getHash(HttpResponse resp) {
return resp.getResponseAsString();
}
};
private final RequestPipeline pipeline = new DefaultRequestPipeline(fetcher, cache, oauth,
new DefaultResponseRewriterRegistry(null, null), new NoOpInvalidationService(), helper);
@Test
public void authTypeNoneNotCached() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
fetcher.response = new HttpResponse("response");
HttpResponse response = pipeline.execute(request);
assertEquals(request, fetcher.request);
assertEquals(fetcher.response, response);
assertEquals(response, cache.data.get(DEFAULT_URI));
assertEquals(1, cache.readCount);
assertEquals(1, cache.writeCount);
assertEquals(1, fetcher.fetchCount);
assertEquals(1, response.getMetadata().size());
assertEquals("response",
response.getMetadata().get(HttpResponseMetadataHelper.DATA_HASH));
}
@Test
public void verifyHashCode() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
fetcher.response = new HttpResponse("response");
RequestPipeline pipeline = new DefaultRequestPipeline(fetcher, cache, oauth,
new DefaultResponseRewriterRegistry(null, null), new NoOpInvalidationService(),
new HttpResponseMetadataHelper());
HttpResponse response = pipeline.execute(request);
assertEquals(1, response.getMetadata().size());
assertEquals("q7u8tbpmidtu1gtqhjv0kb0rvo",
response.getMetadata().get(HttpResponseMetadataHelper.DATA_HASH));
}
@Test
public void authTypeNoneWasCached() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
HttpResponse cached = new HttpResponse("cached");
cache.data.put(DEFAULT_URI, cached);
HttpResponse response = pipeline.execute(request);
assertEquals(cached, response);
assertEquals(1, cache.readCount);
assertEquals(0, cache.writeCount);
assertEquals(0, fetcher.fetchCount);
}
@Test
public void authTypeNoneWasCachedButStale() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
HttpResponse cached = new HttpResponseBuilder().setStrictNoCache().create();
cache.data.put(DEFAULT_URI, cached);
HttpResponse fetched = new HttpResponse("fetched");
fetcher.response = fetched;
HttpResponse response = pipeline.execute(request);
assertEquals(fetched, response);
assertEquals(request, fetcher.request);
assertEquals(fetched, cache.data.get(DEFAULT_URI));
assertEquals(1, cache.readCount);
assertEquals(1, cache.writeCount);
assertEquals(1, fetcher.fetchCount);
assertEquals(1, response.getMetadata().size());
assertEquals("fetched",
response.getMetadata().get(HttpResponseMetadataHelper.DATA_HASH));
}
@Test
public void authTypeNoneStaleCachedServed() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
HttpResponse cached = new HttpResponseBuilder().setCacheTtl(-1).create();
cache.data.put(DEFAULT_URI, cached);
fetcher.response = HttpResponse.error();
HttpResponse response = pipeline.execute(request);
assertEquals(cached, response); // cached item is served instead of 500
assertEquals(request, fetcher.request);
assertEquals(1, cache.readCount);
assertEquals(0, cache.writeCount);
assertEquals(1, fetcher.fetchCount);
}
@Test
public void authTypeNoneWasCachedErrorStale() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE);
HttpResponse cached = new HttpResponseBuilder()
.setCacheTtl(-1)
.setHttpStatusCode(401)
.create();
cache.data.put(DEFAULT_URI, cached);
HttpResponse fetched = HttpResponse.error();
fetcher.response = fetched;
HttpResponse response = pipeline.execute(request);
assertEquals(fetched, response); // 500 served because cached is an error (401)
assertEquals(request, fetcher.request);
assertEquals(fetched, cache.data.get(DEFAULT_URI));
assertEquals(1, cache.readCount);
assertEquals(1, cache.writeCount);
assertEquals(1, fetcher.fetchCount);
}
@Test
public void authTypeNoneIgnoreCache() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.NONE)
.setIgnoreCache(true);
HttpResponse fetched = new HttpResponse("fetched");
fetcher.response = fetched;
HttpResponse response = pipeline.execute(request);
assertEquals(fetched, response);
assertEquals(request, fetcher.request);
assertEquals(0, cache.readCount);
assertEquals(0, cache.writeCount);
assertEquals(1, fetcher.fetchCount);
}
@Test
public void authTypeOAuthNotCached() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.OAUTH);
oauth.httpResponse = new HttpResponse("oauth result");
HttpResponse response = pipeline.execute(request);
assertEquals(oauth.httpResponse, response);
assertEquals(request, oauth.httpRequest);
assertEquals(response, cache.data.get(DEFAULT_URI));
assertEquals(1, oauth.fetchCount);
assertEquals(0, fetcher.fetchCount);
assertEquals(1, cache.readCount);
assertEquals(1, cache.writeCount);
}
@Test
public void authTypeOAuthWasCached() throws Exception {
HttpRequest request = new HttpRequest(DEFAULT_URI)
.setAuthType(AuthType.OAUTH);
HttpResponse cached = new HttpResponse("cached");
cache.data.put(DEFAULT_URI, cached);
HttpResponse response = pipeline.execute(request);
assertEquals(cached, response);
assertEquals(0, oauth.fetchCount);
assertEquals(0, fetcher.fetchCount);
assertEquals(1, cache.readCount);
assertEquals(0, cache.writeCount);
}
public static class FakeHttpFetcher implements HttpFetcher {
protected HttpRequest request;
protected HttpResponse response;
protected int fetchCount = 0;
protected FakeHttpFetcher() {
}
public HttpResponse fetch(HttpRequest request) throws GadgetException {
fetchCount++;
this.request = request;
if (response == null) {
throw new GadgetException(GadgetException.Code.FAILED_TO_RETRIEVE_CONTENT);
}
return response;
}
}
public static class FakeHttpCache implements HttpCache {
protected final Map<Uri, HttpResponse> data = Maps.newHashMap();
protected int writeCount = 0;
protected int readCount = 0;
protected FakeHttpCache() {
}
public boolean addResponse(HttpRequest request, HttpResponse response) {
writeCount++;
data.put(request.getUri(), response);
return true;
}
public HttpResponse getResponse(HttpRequest request) {
readCount++;
return data.get(request.getUri());
}
public HttpResponse removeResponse(HttpRequest key) {
throw new UnsupportedOperationException();
}
public String createKey(HttpRequest request) {
return request.getUri().getQuery();
}
}
public static class FakeOAuthRequestProvider implements Provider<OAuthRequest> {
protected int fetchCount = 0;
protected HttpRequest httpRequest;
protected HttpResponse httpResponse;
protected FakeOAuthRequestProvider() {
}
private final OAuthRequest oauthRequest = new OAuthRequest(null, null) {
@Override
public HttpResponse fetch(HttpRequest request) {
fetchCount++;
httpRequest = request;
return httpResponse;
}
};
public OAuthRequest get() {
return oauthRequest;
}
}
}