MockingCaravanHttpClient.java
/*
* #%L
* wcm.io
* %%
* Copyright (C) 2014 wcm.io
* %%
* Licensed 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.
* #L%
*/
package io.wcm.caravan.testing.http;
import io.wcm.caravan.io.http.CaravanHttpClient;
import io.wcm.caravan.io.http.request.CaravanHttpRequest;
import io.wcm.caravan.io.http.response.CaravanHttpResponse;
import io.wcm.caravan.io.http.response.CaravanHttpResponseBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.http.HttpStatus;
import org.osgi.annotation.versioning.ProviderType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rx.Observable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/**
* Mocking implementation of {@link CaravanHttpClient} for tests. Use mockRequest methods to register a response.
* Returns a 404 NOT FOUND response if there is
* no response registered for the request.
*/
@ProviderType
public final class MockingCaravanHttpClient implements CaravanHttpClient {
private static final Logger LOGGER = LoggerFactory.getLogger(MockingCaravanHttpClient.class);
private static final CaravanHttpResponse NOT_FOUND = new CaravanHttpResponseBuilder()
.status(HttpStatus.SC_NOT_FOUND)
.reason("Not Found")
.build();
private final List<RequestMatcher> requestMatchers = new ArrayList<>();
private Boolean hasValidConfigurationAll;
private Map<String, Boolean> hasValidConfiguration = Maps.newConcurrentMap();
private Map<RequestMatcher, AtomicInteger> matchingCounter = Maps.newHashMap();
@Override
public Observable<CaravanHttpResponse> execute(final CaravanHttpRequest request) {
return execute(request, Observable.just(NOT_FOUND));
}
@Override
public Observable<CaravanHttpResponse> execute(final CaravanHttpRequest request, final Observable<CaravanHttpResponse> fallback) {
String serviceId = request.getServiceId();
String url = request.getUrl();
for (RequestMatcher matcher : requestMatchers) {
if (matcher.matches(serviceId, url)) {
matchingCounter.get(matcher).incrementAndGet();
return Observable.just(matcher.getResponse());
}
}
LOGGER.warn("No response registered for url: " + url);
return fallback;
}
@Override
public boolean hasValidConfiguration(String serviceId) {
Boolean validConfig = hasValidConfiguration.get(serviceId);
if (validConfig == null) {
if (hasValidConfigurationAll != null) {
return hasValidConfigurationAll.booleanValue();
}
else {
return true;
}
}
else {
return validConfig.booleanValue();
}
}
/**
* Set valid configuration for a given service (if not set defaults to true)
* @param serviceId Service ID
* @param valid Configuration valid status
*/
public void setValidConfiguration(String serviceId, boolean valid) {
hasValidConfiguration.put(serviceId, valid);
}
/**
* Set valid configuration for any service.
* @param valid Configuration valid status
*/
public void setValidConfigurationAnyService(boolean valid) {
hasValidConfigurationAll = valid;
}
/**
* Define which request should be mocked with which response.
* @return Request matcher
*/
public RequestMatcher mockRequest() {
RequestMatcher matcher = new RequestMatcher();
requestMatchers.add(matcher);
matchingCounter.put(matcher, new AtomicInteger(0));
return matcher;
}
/**
* @return Request Matcher counter
*/
public Map<RequestMatcher, AtomicInteger> getMatchingCounter() {
return ImmutableMap.copyOf(matchingCounter);
}
/**
* @return Returns the requestMatchers.
*/
public List<RequestMatcher> getRequestMatchers() {
return this.requestMatchers;
}
/**
* Returns the number of invocations for the first {@link RequestMatcher} fitting the given {@code serviceId} and
* {@code url}.
* @param serviceId Logical service name
* @param url (Partial) URL
* @return Number of invocations
*/
public int getMatchingCount(String serviceId, String url) {
for (RequestMatcher matcher : requestMatchers) {
if (matcher.matches(serviceId, url)) {
return matchingCounter.get(matcher).get();
}
}
return 0;
}
}